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

/**
 * ExpressJS-style routes for handling the various URLs for the translation utility.
 *
 * @author John Blanco
 */

// modules
var https = require( 'https' );
var LocaleInfo = require( './LocaleInfo' );
var TranslatableSimInfo = require( './TranslatableSimInfo' );
var simInfoArray = require( '../data/simInfoArray.json' );
var TranslationUtils = require( './TranslationUtils' );
var winston = require( 'winston' );
var request = require( 'request' );
var _ = require( 'underscore' );
var contains = TranslationUtils.contains;
var getGhClient = TranslationUtils.getGhClient;
var commit = TranslationUtils.commit;
var stringify = TranslationUtils.stringify;

// utility function for sending the user to the login page
function sendUserToLoginPage( res, host, destinationUrl ) {
  res.render( 'login-required.html', { title: 'Login Required', host: host, destinationUrl: destinationUrl } );
}

// utility function for presenting escaped HTML
function escapeHTML( s ) {
  return s.replace( /&/g, '&' )
    .replace( /"/g, '"' )
    .replace( /</g, '<' )
    .replace( />/g, '>' );
}

/**
 * Route that checks whether the user has a valid session in progress.  This works by looking for the cookie set when
 * the user logs in to the main web site and, if said cookie is present, uses it to obtain user information from the
 * 'main' web site.
 *
 * TODO: As of mid-Feb 2015, this checks the session on every page serve.  It would probably be better to do some local
 * management of sessions, and only re-check them periodically.
 *
 * @param req
 * @param res
 * @param next
 */
module.exports.checkForValidSession = function( req, res, next ) {

  if ( req.get( 'host' ).indexOf( 'localhost' ) === 0 ) {
    // bypass credential evaluation to allow testing on localhost
    winston.log( 'warn', 'Bypassing session validation to allow testing on localhost' );
    next(); // send to next route
    return;
  }

  // check whether the session cookie exists
  winston.log( 'info', 'Checking for login cookie' );
  var cookie = req.cookies.JSESSIONID;
  if ( cookie === undefined ) {
    // no session cookie present, the user must log in
    winston.log( 'info', 'session cookie not found, sending to login page' );
    winston.log( 'info', 'host = ' + req.get( 'host' ) );
    winston.log( 'info', 'req.url = ' + req.url );
    sendUserToLoginPage( res, req.get( 'host' ), req.url );
  }
  else {
    // session cookie was present, attempt to obtain session information
    var options = {
      host: req.get( 'host' ),
      path: '/services/check-login',
      method: 'GET',
      headers: {
        'Cookie': 'JSESSIONID=' + cookie
      }
    };

    var sessionDataRequestCallback = function( response ) {
      var data = '';

      // another chunk of data has been received, so append it
      response.on( 'data', function( chunk ) {
        data += chunk;
      } );

      // the whole response has been received - see if the credentials are valid
      response.on( 'end', function() {
        winston.log( 'info', 'data received: ' + data );
        var userData = JSON.parse( data );
        if ( userData.teamMember ) {
          winston.log( 'info', 'User is detected as being a PhET team member' );
          req.session.teamMember = true;
        }
        else {
          req.session.teamMember = false;
        }
        if ( userData.trustedTranslator ) {
          winston.log( 'info', 'User is detected as being a PhET team member' );
          req.session.trustedTranslator = true;
        }
        else {
          req.session.trustedTranslator = false;
        }
        if ( userData.loggedIn ) {
          winston.log( 'info', 'credentials obtained, user is logged in, moving to next step' );
          next(); // send to next route
        }
        else {
          // user is not logged in, send them to the login page
          sendUserToLoginPage( res, req.get( 'host' ), req.url );
        }
      } );
    };

    var requestCredentials = https.request( options, sessionDataRequestCallback );

    // error handling
    requestCredentials.on( 'error', function( err ) {
      winston.log( 'error', 'error retrieving session data: ' + err );
      res.render( 'error.html', {
          title: 'Translation Utility Error',
          message: 'Unable to obtain user credentials',
          errorDetails: err,
          timestamp: new Date().getTime()
        }
      );
    } );

    // send the request
    requestCredentials.end();
  }
};

/**
 * Route that lets the user choose a simulation and language to translate, and subsequently routes them to the actual
 * translation page.
 *
 * @param req
 * @param res
 * @param next
 */
module.exports.chooseSimulationAndLanguage = function( req, res ) {

  // Pull the username from the cookie
  var username = req.cookies[ 'sign-in-panel.sign-in-form.username' ] || 'not logged in';

  res.render( 'translate-home.html', {
    title: 'PhET Translation Utility',
    simInfoArray: simInfoArray,
    username: username
  } );
};

/**
 * Route that creates a page for translating a given simulation to a given language.  The simulation ID and the target
 * language are extracted from the incoming request.
 *
 * @param req
 * @param res
 */
module.exports.translateSimulation = function( req, res ) {
  var simName = req.param( 'simName' );
  var targetLocale = req.param( 'targetLocale' );
  var rawGithub = 'https://raw.githubusercontent.com';
  var activeSimsPath = '/phetsims/chipper/master/data/active-sims';

  // get the url of the live sim (from simInfoArray)
  var simUrl;
  for ( var i = 0; i < simInfoArray.length; i++ ) {
    if ( simInfoArray[ i ].projectName === simName ) {
      simUrl = simInfoArray[ i ].testUrl;
      break;
    }
  }

  // extract strings from the live sim's html file
  request( simUrl, function( error, response, body ) {
    if ( !error && response.statusCode == 200 ) {
      var i;
      var sims; // array of all active sims

      // initialize the sims array from the active-sims file in chipper
      request( rawGithub + activeSimsPath, function( error, response, body ) {
        if ( !error && response.statusCode == 200 ) {
          sims = body.toString().split( '\n' );
        }
        else {
          winston.log( 'error', error );
        }
        finished();
      } );

      // extract strings from the sim's html file and store them in the extractedStrings array
      // extractedStrings in an array of objects of the form { projectName: 'color-vision', stringKeys: [ 'key1', 'key2', ... ] }
      var extractedStrings = [];
      TranslationUtils.extractStrings( extractedStrings, body );

      var englishStrings = {}; // object to hold the English strings
      var translatedStrings = {}; // object to hold the already translated strings

      var numberOfReposWithRequiredStrings = extractedStrings.length;

      /*
       * finished() must be called numberOfReposWithRequiredStrings * 2 + 1 times. This is the number of http requests to github that
       * need to return before we are ready to render the page. We make two requests per repo - one for the English strings from the sims's
       * repo, and one for the translated strings from babel - plus one more for the request to get the active sims list from chipper.
       */
      var finished = _.after( numberOfReposWithRequiredStrings * 2 + 1, function() {
        var simStringsArray = [];
        var commonStringsArray = [];

        // iterate over all projects that this sim takes strings from
        for ( i = 0; i < extractedStrings.length; i++ ) {
          var project = extractedStrings[ i ];
          var strings = englishStrings[ project.projectName ];

          // put the strings under common strings or sim strings depending on which project they are from
          var array = ( contains( sims, project.projectName ) ) ? simStringsArray : commonStringsArray;
          for ( var j = 0; j < project.stringKeys.length; j++ ) {
            var key = project.stringKeys[ j ];
            if ( strings.hasOwnProperty( key ) ) {
              array.push( {
                key: key,
                string: escapeHTML( strings[ key ] ),
                value: translatedStrings[ project.projectName ][ key ] ? escapeHTML( translatedStrings[ project.projectName ][ key ].value ) : '',
                repo: project.projectName
              } );
            }
            // if an english string isn't found for a key, use the key name instead
            else {
              array.push( {
                key: key,
                string: key,
                value: translatedStrings[ project.projectName ][ key ] ? escapeHTML( translatedStrings[ project.projectName ][ key ].value ) : '',
                repo: project.projectName
              } );
            }
          }
        }

        // Pull the username from the cookie
        var username = req.cookies[ 'sign-in-panel.sign-in-form.username' ] || 'not logged in';

        // Assemble the data that will be supplied to the template.
        var templateData = {
          title: "PhET Translation Utility",
          subtitle: "Please enter a translation for each English string:",
          destinationLanguage: LocaleInfo.localeToLanguageString( targetLocale ),
          simStringsArray: simStringsArray,
          commonStringsArray: commonStringsArray,
          simName: simName,
          simUrl: TranslatableSimInfo.getSimInfoByProjectName( simName ).testUrl,
          username: username,
          trustedTranslator: ( req.session.trustedTranslator ) ? req.session.trustedTranslator : false
        };

        // Render the page.
        res.render( 'translate-sim.html', templateData );
      } );

      // send requests to github for the common code English strings
      for ( i = 0; i < extractedStrings.length; i++ ) {
        (function( i ) {
          var projectName = extractedStrings[ i ].projectName;
          var stringsFilePath = rawGithub + '/phetsims/' + projectName + '/master/strings/' + projectName + '-strings_en.json';
          var translatedStringsPath = rawGithub + '/phetsims/babel/master/' + projectName + '/' + projectName + '-strings_' + targetLocale + '.json';

          request( stringsFilePath, function( error, response, body ) {
            if ( !error && response.statusCode == 200 ) {
              englishStrings[ projectName ] = JSON.parse( body );
            }
            else {
              winston.log( 'error', error );
            }
            finished();
          } );

          request( translatedStringsPath, function( error, response, body ) {
            if ( !error && response.statusCode == 200 ) {
              translatedStrings[ projectName ] = JSON.parse( body );
            }
            else {
              winston.log( 'warn', 'Github responded with a ' + response.statusCode + ' status code for url ' + translatedStringsPath +
                                   '. Mostly likely the file does not exist on github' );
              translatedStrings[ projectName ] = {}; // add an empty object with the project name key so key lookups don't fail later on
            }
            finished();
          } );
        })( i );
      }
    }
    else {
      winston.log( 'error', error );
      res.send( 'Error: Sim data not found' );
    }
  } );
};

module.exports.submitStrings = function( req, res ) {
  var targetLocale = req.param( 'targetLocale' );
  var ghClient = getGhClient();
  var babel = ghClient.repo( 'phetsims/babel' );

  var repos = {};

  for ( var string in req.body ) {
    if ( req.body.hasOwnProperty( string ) ) {
      var repoAndKey = string.split( ' ' );
      var repo = repoAndKey[ 0 ];
      var key = repoAndKey[ 1 ];

      if ( !repos[ repo ] ) {
        repos[ repo ] = [];
      }
      if ( req.body[ string ] !== '' ) {
        var stringObject = {};
        stringObject[ key ] = { 'value': req.body[ string ], 'history': [] };
        repos[ repo ].push( stringObject );
      }
    }
  }

  for ( var repository in repos ) {
    if ( req.body.hasOwnProperty( string ) ) {
      var branch = 'tests';
      var strings = repos[ repository ];
      var content = stringify( strings );

      if ( content.length ) {
        var file = repository + '/' + repository + '-strings_' + targetLocale + '.json';
        var commitMessage = Date.now() + ' automated commit from rosetta for file ' + file;

        commit( babel, file, content, commitMessage, branch );
        winston.log( 'info', commitMessage );
      }
    }
  }

  res.send( 'Strings submitted' );
};

/**
 * Default route for when a page is not found in the translation utility.
 *
 * @param req
 * @param res
 */
module.exports.pageNotFound = function( req, res ) {
  res.send( '
Error: Page not found.  URL = ' + req.url + '
' );
};

/**
 * Route for extracting strings from a build sim, see TranslationUtils.extractStrings.
 */
module.exports.extractStringsAPI = TranslationUtils.extractStringsAPI;
<commit_msg>add stub for history; add user data to session<commit_after>// Copyright 2002-2015, University of Colorado Boulder

/**
 * ExpressJS-style routes for handling the various URLs for the translation utility.
 *
 * @author John Blanco
 */

// modules
var https = require( 'https' );
var LocaleInfo = require( './LocaleInfo' );
var TranslatableSimInfo = require( './TranslatableSimInfo' );
var simInfoArray = require( '../data/simInfoArray.json' );
var TranslationUtils = require( './TranslationUtils' );
var winston = require( 'winston' );
var request = require( 'request' );
var _ = require( 'underscore' );
var contains = TranslationUtils.contains;
var getGhClient = TranslationUtils.getGhClient;
var commit = TranslationUtils.commit;
var stringify = TranslationUtils.stringify;

// utility function for sending the user to the login page
function sendUserToLoginPage( res, host, destinationUrl ) {
  res.render( 'login-required.html', { title: 'Login Required', host: host, destinationUrl: destinationUrl } );
}

// utility function for presenting escaped HTML
function escapeHTML( s ) {
  return s.replace( /&/g, '&' )
    .replace( /"/g, '"' )
    .replace( /</g, '<' )
    .replace( />/g, '>' );
}

/**
 * Route that checks whether the user has a valid session in progress.  This works by looking for the cookie set when
 * the user logs in to the main web site and, if said cookie is present, uses it to obtain user information from the
 * 'main' web site.
 *
 * TODO: As of mid-Feb 2015, this checks the session on every page serve.  It would probably be better to do some local
 * management of sessions, and only re-check them periodically.
 *
 * @param req
 * @param res
 * @param next
 */
module.exports.checkForValidSession = function( req, res, next ) {

  if ( req.get( 'host' ).indexOf( 'localhost' ) === 0 ) {
    // bypass credential evaluation to allow testing on localhost
    winston.log( 'warn', 'Bypassing session validation to allow testing on localhost' );
    next(); // send to next route
    return;
  }

  // check whether the session cookie exists
  winston.log( 'info', 'Checking for login cookie' );
  var cookie = req.cookies.JSESSIONID;
  if ( cookie === undefined ) {
    // no session cookie present, the user must log in
    winston.log( 'info', 'session cookie not found, sending to login page' );
    winston.log( 'info', 'host = ' + req.get( 'host' ) );
    winston.log( 'info', 'req.url = ' + req.url );
    sendUserToLoginPage( res, req.get( 'host' ), req.url );
  }
  else {
    // session cookie was present, attempt to obtain session information
    var options = {
      host: req.get( 'host' ),
      path: '/services/check-login',
      method: 'GET',
      headers: {
        'Cookie': 'JSESSIONID=' + cookie
      }
    };

    var sessionDataRequestCallback = function( response ) {
      var data = '';

      // another chunk of data has been received, so append it
      response.on( 'data', function( chunk ) {
        data += chunk;
      } );

      // the whole response has been received - see if the credentials are valid
      response.on( 'end', function() {
        winston.log( 'info', 'data received: ' + data );
        var userData = JSON.parse( data );
        if ( userData.loggedIn ) {
          winston.log( 'info', 'credentials obtained, user is logged in, moving to next step' );
          req.session.teamMember = userData.teamMember;
          req.session.trustedTranslator = userData.trustedTranslator;
          req.session.userId = userData.userId;
          req.session.username = userData.username;
          next(); // send to next route
        }
        else {
          // user is not logged in, send them to the login page
          sendUserToLoginPage( res, req.get( 'host' ), req.url );
        }
      } );
    };

    var requestCredentials = https.request( options, sessionDataRequestCallback );

    // error handling
    requestCredentials.on( 'error', function( err ) {
      winston.log( 'error', 'error retrieving session data: ' + err );
      res.render( 'error.html', {
          title: 'Translation Utility Error',
          message: 'Unable to obtain user credentials',
          errorDetails: err,
          timestamp: new Date().getTime()
        }
      );
    } );

    // send the request
    requestCredentials.end();
  }
};

/**
 * Route that lets the user choose a simulation and language to translate, and subsequently routes them to the actual
 * translation page.
 *
 * @param req
 * @param res
 * @param next
 */
module.exports.chooseSimulationAndLanguage = function( req, res ) {

  // Pull the username from the cookie
  var username = req.cookies[ 'sign-in-panel.sign-in-form.username' ] || 'not logged in';

  res.render( 'translate-home.html', {
    title: 'PhET Translation Utility',
    simInfoArray: simInfoArray,
    username: username
  } );
};

/**
 * Route that creates a page for translating a given simulation to a given language.  The simulation ID and the target
 * language are extracted from the incoming request.
 *
 * @param req
 * @param res
 */
module.exports.translateSimulation = function( req, res ) {
  var simName = req.param( 'simName' );
  var targetLocale = req.param( 'targetLocale' );
  var rawGithub = 'https://raw.githubusercontent.com';
  var activeSimsPath = '/phetsims/chipper/master/data/active-sims';

  // get the url of the live sim (from simInfoArray)
  var simUrl;
  for ( var i = 0; i < simInfoArray.length; i++ ) {
    if ( simInfoArray[ i ].projectName === simName ) {
      simUrl = simInfoArray[ i ].testUrl;
      break;
    }
  }

  // extract strings from the live sim's html file
  request( simUrl, function( error, response, body ) {
    if ( !error && response.statusCode == 200 ) {
      var i;
      var sims; // array of all active sims

      // initialize the sims array from the active-sims file in chipper
      request( rawGithub + activeSimsPath, function( error, response, body ) {
        if ( !error && response.statusCode == 200 ) {
          sims = body.toString().split( '\n' );
        }
        else {
          winston.log( 'error', error );
        }
        finished();
      } );

      // extract strings from the sim's html file and store them in the extractedStrings array
      // extractedStrings in an array of objects of the form { projectName: 'color-vision', stringKeys: [ 'key1', 'key2', ... ] }
      var extractedStrings = [];
      TranslationUtils.extractStrings( extractedStrings, body );

      var englishStrings = {}; // object to hold the English strings
      var translatedStrings = {}; // object to hold the already translated strings

      var numberOfReposWithRequiredStrings = extractedStrings.length;

      /*
       * finished() must be called numberOfReposWithRequiredStrings * 2 + 1 times. This is the number of http requests to github that
       * need to return before we are ready to render the page. We make two requests per repo - one for the English strings from the sims's
       * repo, and one for the translated strings from babel - plus one more for the request to get the active sims list from chipper.
       */
      var finished = _.after( numberOfReposWithRequiredStrings * 2 + 1, function() {
        var simStringsArray = [];
        var commonStringsArray = [];

        // iterate over all projects that this sim takes strings from
        for ( i = 0; i < extractedStrings.length; i++ ) {
          var project = extractedStrings[ i ];
          var strings = englishStrings[ project.projectName ];

          // put the strings under common strings or sim strings depending on which project they are from
          var array = ( contains( sims, project.projectName ) ) ? simStringsArray : commonStringsArray;
          for ( var j = 0; j < project.stringKeys.length; j++ ) {
            var key = project.stringKeys[ j ];
            if ( strings.hasOwnProperty( key ) ) {
              array.push( {
                key: key,
                string: escapeHTML( strings[ key ] ),
                value: translatedStrings[ project.projectName ][ key ] ? escapeHTML( translatedStrings[ project.projectName ][ key ].value ) : '',
                repo: project.projectName
              } );
            }
            // if an english string isn't found for a key, use the key name instead
            else {
              array.push( {
                key: key,
                string: key,
                value: translatedStrings[ project.projectName ][ key ] ? escapeHTML( translatedStrings[ project.projectName ][ key ].value ) : '',
                repo: project.projectName
              } );
            }
          }
        }

        // Pull the username from the cookie
        var username = req.cookies[ 'sign-in-panel.sign-in-form.username' ] || 'not logged in';

        // Assemble the data that will be supplied to the template.
        var templateData = {
          title: "PhET Translation Utility",
          subtitle: "Please enter a translation for each English string:",
          destinationLanguage: LocaleInfo.localeToLanguageString( targetLocale ),
          simStringsArray: simStringsArray,
          commonStringsArray: commonStringsArray,
          simName: simName,
          simUrl: TranslatableSimInfo.getSimInfoByProjectName( simName ).testUrl,
          username: username,
          trustedTranslator: ( req.session.trustedTranslator ) ? req.session.trustedTranslator : false
        };

        // Render the page.
        res.render( 'translate-sim.html', templateData );
      } );

      // send requests to github for the common code English strings
      for ( i = 0; i < extractedStrings.length; i++ ) {
        (function( i ) {
          var projectName = extractedStrings[ i ].projectName;
          var stringsFilePath = rawGithub + '/phetsims/' + projectName + '/master/strings/' + projectName + '-strings_en.json';
          var translatedStringsPath = rawGithub + '/phetsims/babel/master/' + projectName + '/' + projectName + '-strings_' + targetLocale + '.json';

          request( stringsFilePath, function( error, response, body ) {
            if ( !error && response.statusCode == 200 ) {
              englishStrings[ projectName ] = JSON.parse( body );
            }
            else {
              winston.log( 'error', error );
            }
            finished();
          } );

          request( translatedStringsPath, function( error, response, body ) {
            if ( !error && response.statusCode == 200 ) {
              translatedStrings[ projectName ] = JSON.parse( body );
            }
            else {
              winston.log( 'warn', 'Github responded with a ' + response.statusCode + ' status code for url ' + translatedStringsPath +
                                   '. Mostly likely the file does not exist on github' );
              translatedStrings[ projectName ] = {}; // add an empty object with the project name key so key lookups don't fail later on
            }
            finished();
          } );
        })( i );
      }
    }
    else {
      winston.log( 'error', error );
      res.send( 'Error: Sim data not found' );
    }
  } );
};

module.exports.submitStrings = function( req, res ) {
  var targetLocale = req.param( 'targetLocale' );
  var ghClient = getGhClient();
  var babel = ghClient.repo( 'phetsims/babel' );

  var repos = {};

  for ( var string in req.body ) {
    if ( req.body.hasOwnProperty( string ) ) {
      var repoAndKey = string.split( ' ' );
      var repo = repoAndKey[ 0 ];
      var key = repoAndKey[ 1 ];

      if ( !repos[ repo ] ) {
        repos[ repo ] = [];
      }
      if ( req.body[ string ] !== '' ) {
        var stringObject = {};
        stringObject[ key ] = {
          value: req.body[ string ], history: [
            // TODO: implement proper history
            //{
            //  userId: ( req.session.userId ) ? req.session.userId : 'phet',
            //  timestamp: Date.now(),
            //  oldValue: null,
            //  newValue: null,
            //  explanation: null
            //}
          ]
        };
        repos[ repo ].push( stringObject );
      }
    }
  }

  for ( var repository in repos ) {
    if ( req.body.hasOwnProperty( string ) ) {
      var branch = 'tests';
      var strings = repos[ repository ];
      var content = stringify( strings );

      if ( content.length ) {
        var file = repository + '/' + repository + '-strings_' + targetLocale + '.json';
        var commitMessage = Date.now() + ' automated commit from rosetta for file ' + file;

        commit( babel, file, content, commitMessage, branch );
        winston.log( 'info', commitMessage );
      }
    }
  }

  res.send( 'Strings submitted' );
};

/**
 * Default route for when a page is not found in the translation utility.
 *
 * @param req
 * @param res
 */
module.exports.pageNotFound = function( req, res ) {
  res.send( '
Error: Page not found.  URL = ' + req.url + '
' );
};

/**
 * Route for extracting strings from a build sim, see TranslationUtils.extractStrings.
 */
module.exports.extractStringsAPI = TranslationUtils.extractStringsAPI;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { SplitButton, Button, MenuItem } from 'react-bootstrap';

import { DataApi } from 'loom-data';

import FileConsts from '../../utils/Consts/FileConsts';
import PageConsts from '../../utils/Consts/PageConsts';
import { EntitySetPropType } from './EntitySetStorage';
import styles from './entityset.module.css';

const MAX_DESCRIPTION_LENGTH = 300;

class ExpandableText extends React.Component {
  static propTypes = {
    text: PropTypes.string,
    maxLength: PropTypes.number
  };

  constructor(props) {
    super(props);
    this.state = {
      isOpen: false
    };

    this.switchState = () => {
      this.setState({ isOpen: !this.state.isOpen });
    };
  }

  render() {
    const { text, maxLength } = this.props;
    if (text.length <= maxLength) {
      return (
{text}
);
    }

    const { isOpen } = this.state;
    let controlText,
      displayText;
    if (isOpen) {
      controlText = 'Read less';
      displayText = text;
    } else {
      controlText = 'Read more';
      displayText = `${text.substring(0, maxLength)}...`;
    }

    return (

        {displayText}
        <Button bsStyle="link" className={styles.expandTextButton} onClick={this.switchState}>{controlText}</Button>

    );

  }
}

class ActionDropdown extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired,
    showDetails: PropTypes.bool
  };

  render() {
    const { entitySet } = this.props;
    const type = entitySet.type;

    let details;
    if (this.props.showDetails) {
      details = (

          <Link to={`/entitysets/${this.props.entitySet.id}`}>
            View Details
          </Link>

      );
    }

    return (
      <SplitButton pullRight title="Actions" id="action-dropdown">
        {details}
        <MenuItem header>Download</MenuItem>
        <MenuItem href={DataApi.getAllEntitiesOfTypeInSetFileUrl(type, entitySet.name, FileConsts.CSV)}>CSV</MenuItem>
        <MenuItem href={DataApi.getAllEntitiesOfTypeInSetFileUrl(type, entitySet.name, FileConsts.JSON)}>JSON</MenuItem>
        <MenuItem divider/>

          <Link
            to={{
              pathname: `/${PageConsts.VISUALIZE}`,
              query: {
                name: entitySet.name,
                typeNamespace: type.namespace,
                typeName: type.name
              }
            }}>
            Visualize
          </Link>

      </SplitButton>
    );
  }
}

/* EntitySet Components */
export class EntitySetSummary extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired
  };

  render() {
    const { entitySet } = this.props;

    let description;
    if (entitySet.description) {
      description = (<ExpandableText maxLength={MAX_DESCRIPTION_LENGTH} text={entitySet.description}/>);
    } else {
      description = (No description available);
    }

    return (

            {entitySet.title}
            {entitySet.type.namespace}.{entitySet.type.name}

            <ActionDropdown entitySet={entitySet} showDetails={true}/>

        {description}

    );
  }
}

// TODO: Reduxify and attach EntitySetDetail to router
export class EntitySetDetail extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired
  };

  constructor(props) {
    super(props);
    this.state = {
      editing: false,
      showPanel: false,
      permissionRequestStatus: {
        display: styles.hidden,
        msg: ''
      }
    };
  }

  render() {
    const { entitySet } = this.props;

    return (

            {entitySet.title}
            {entitySet.type.namespace}.{entitySet.type.name}

            <ActionDropdown entitySet={entitySet} />

        <ExpandableText maxLength={MAX_DESCRIPTION_LENGTH} text={entitySet.description} />

    );
  }
}
<commit_msg>Upgraded loom-data via npm link<commit_after>import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import { SplitButton, Button, MenuItem } from 'react-bootstrap';

import { DataApi } from 'loom-data';

import FileConsts from '../../utils/Consts/FileConsts';
import PageConsts from '../../utils/Consts/PageConsts';
import { EntitySetPropType } from './EntitySetStorage';
import styles from './entityset.module.css';

const MAX_DESCRIPTION_LENGTH = 300;

class ExpandableText extends React.Component {
  static propTypes = {
    text: PropTypes.string,
    maxLength: PropTypes.number
  };

  constructor(props) {
    super(props);
    this.state = {
      isOpen: false
    };

    this.switchState = () => {
      this.setState({ isOpen: !this.state.isOpen });
    };
  }

  render() {
    const { text, maxLength } = this.props;
    if (text.length <= maxLength) {
      return (
{text}
);
    }

    const { isOpen } = this.state;
    let controlText,
      displayText;
    if (isOpen) {
      controlText = 'Read less';
      displayText = text;
    } else {
      controlText = 'Read more';
      displayText = `${text.substring(0, maxLength)}...`;
    }

    return (

        {displayText}
        <Button bsStyle="link" className={styles.expandTextButton} onClick={this.switchState}>{controlText}</Button>

    );

  }
}

class ActionDropdown extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired,
    showDetails: PropTypes.bool
  };

  render() {
    const { entitySet } = this.props;
    const type = entitySet.type;

    let details;
    if (this.props.showDetails) {
      details = (

          <Link to={`/entitysets/${this.props.entitySet.id}`}>
            View Details
          </Link>

      );
    }

    return (
      <SplitButton pullRight title="Actions" id="action-dropdown">
        {details}
        <MenuItem header>Download</MenuItem>
        <MenuItem href={DataApi.getEntitySetDataFileUrl(entitySet.id, FileConsts.CSV)}>CSV</MenuItem>
        <MenuItem href={DataApi.getEntitySetDataFileUrl(entitySet.id, FileConsts.JSON)}>JSON</MenuItem>
        <MenuItem divider/>

          <Link
            to={{
              pathname: `/${PageConsts.VISUALIZE}`,
              query: {
                name: entitySet.name,
                typeNamespace: type.namespace,
                typeName: type.name
              }
            }}>
            Visualize
          </Link>

      </SplitButton>
    );
  }
}

/* EntitySet Components */
export class EntitySetSummary extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired
  };

  render() {
    const { entitySet } = this.props;

    let description;
    if (entitySet.description) {
      description = (<ExpandableText maxLength={MAX_DESCRIPTION_LENGTH} text={entitySet.description}/>);
    } else {
      description = (No description available);
    }

    return (

            {entitySet.title}
            {entitySet.type.namespace}.{entitySet.type.name}

            <ActionDropdown entitySet={entitySet} showDetails={true}/>

        {description}

    );
  }
}

// TODO: Reduxify and attach EntitySetDetail to router
export class EntitySetDetail extends React.Component {
  static propTypes = {
    entitySet: EntitySetPropType.isRequired
  };

  constructor(props) {
    super(props);
    this.state = {
      editing: false,
      showPanel: false,
      permissionRequestStatus: {
        display: styles.hidden,
        msg: ''
      }
    };
  }

  render() {
    const { entitySet } = this.props;

    return (

            {entitySet.title}
            {entitySet.type.namespace}.{entitySet.type.name}

            <ActionDropdown entitySet={entitySet} />

        <ExpandableText maxLength={MAX_DESCRIPTION_LENGTH} text={entitySet.description} />

    );
  }
}
<|endoftext|>


<commit_before>var canvas = document.getElementById("mapcanvas");
var c = canvas.getContext("2d");
var myTimer;

// set the dynamic outside the loop
var dynamic = 10;

//loop function
function loop() {

    // change dynamic
    dynamic = dynamic * 1.1;
    x = dynamic;
    y = dynamic * 1.2;

    // stop the the animation if it runs out-of-canvas
    if (x > canvas.width || y > canvas.height) {
        c.clearRect(0, 0, canvas.width, canvas.height);
        clearInterval(myTimer);
        alert("animation done!");
    }

    // clear the canvas for this loop's animation
    c.clearRect(0, 0, canvas.width, canvas.height);
    c.fillStyle = '#87CEEB';

    // draw
    c.beginPath();
    c.arc(x, y, 10, 0, Math.PI * 2, false);
    c.fill();
}

$("#startbtn").click(function(){ dynamic=10; myTimer=setInterval(loop,20); });
<commit_msg>Update script.js<commit_after>(function(window, document, undefined) {
    window.onload = init;
    function init() {
        var canvas = document.getElementById("mapcanvas");
        var c = canvas.getContext("2d");
        var myTimer;

        // set the dynamic outside the loop
        var dynamic = 10;

        //loop function
        function loop() {

            // change dynamic
            dynamic = dynamic * 1.1;
            x = dynamic;
            y = dynamic * 1.2;

            // stop the the animation if it runs out-of-canvas
            if (x > canvas.width || y > canvas.height) {
                c.clearRect(0, 0, canvas.width, canvas.height);
                clearInterval(myTimer);
                alert("animation done!");
            }

            // clear the canvas for this loop's animation
            c.clearRect(0, 0, canvas.width, canvas.height);
            c.fillStyle = '#87CEEB';

            // draw
            c.beginPath();
            c.arc(x, y, 10, 0, Math.PI * 2, false);
            c.fill();
        }

        $("#startbtn").click(function(){ dynamic=10; myTimer=setInterval(loop,20); });
    }
})(window, document, undefined);
<|endoftext|>


<commit_before>/*
 * Filename: sequencediagram.js
 */

var self = this;

/**
 * Create a new SequenceDiagram that let users create sub-sequencediagram.
 * @return {SequenceDiagram}
 */
function SequenceDiagram() {
  self._filename = ''; // Will be set
  self._filepath = ''; // Will be set
  self._proxies = {}; // Will be set
}

SequenceDiagram.prototype.append = function() {
  console.log('documentations documentation uml sequencediagram - append() called')
  // temporarily we do all the file creation and appending in here
  // move most of this logic out to its best location. e.g. at documentation level
  //var fs = self._proxies.proxy().libraries().library().fs(); // DOESN'T WORK!!
  var fs = require('fs');
  var path = self._proxies.proxy().libraries().library().path();
  var filePathAndName = path.join(self._filepath, self._filename);
  var stream = fs.createWriteStream(filePathAndName);
  stream.once('open', function(fd) {
    var html = self.buildHtml();

    stream.end(html);
  });
}

SequenceDiagram.prototype.buildHtml = function() {
  console.log('documentations documentation uml sequencediagram - buitlHTML() called')
  var header = '';
  var body = '';
  // concatenate header string
  // concatenate body string
  return '<!DOCTYPE html>'
       + '' + header + '' + body + '';
};

SequenceDiagram.prototype.filename = function() {
  return self._filename;
}

SequenceDiagram.prototype.setfilename = function(fnOrValue) {
  self._filename = fnOrValue;
}

SequenceDiagram.prototype.filepath = function() {
  return self._filepath;
}

SequenceDiagram.prototype.setfilepath = function(fnOrValue) {
  self._filepath = fnOrValue;
}

SequenceDiagram.prototype.proxies = function() {
  return self._proxies;
}

SequenceDiagram.prototype.setproxies = function(fnOrValue) {
  self._proxies = fnOrValue;
}

module.exports = SequenceDiagram;<commit_msg>Modified<commit_after>/*
 * Filename: sequencediagram.js
 */

var self = this;

/**
 * Create a new SequenceDiagram that let users create sub-sequencediagram.
 * @return {SequenceDiagram}
 */
function SequenceDiagram() {
  self._filename = ''; // Will be set
  self._filepath = ''; // Will be set
  self._proxies = {}; // Will be set
}

SequenceDiagram.prototype.append = function() {
  console.log('documentations documentation uml sequencediagram - append() called')
  // temporarily we do all the file creation and appending in here
  // move most of this logic out to its best location. e.g. at documentation level
  //var fs = self._proxies.proxy().libraries().library().fs(); // DOESN'T WORK!!
  var path = self._proxies.proxy().libraries().library().path();
  var filePathAndName = path.join(self._filepath, self._filename);
  this.ensureExists(self._filepath, 0744, function(err) {
    if (err) { // handle folder creation error
      console.log('documentations documentation uml sequencediagram - error', err)
    }
    else { // we're all good
      var fs = require('fs');
      var stream = fs.createWriteStream(filePathAndName);
      stream.once('open', function(fd) {
        var html = self.buildHtml();

        stream.end(html);
      });
    }
  });
}

SequenceDiagram.prototype.buildHtml = function() {
  console.log('documentations documentation uml sequencediagram - buitlHTML() called')
  var header = '';
  var body = '';
  // concatenate header string
  // concatenate body string
  return '<!DOCTYPE html>'
       + '' + header + '' + body + '';
};

SequenceDiagram.prototype.ensureExists = function(path, mask, cb) {
  if (typeof mask == 'function') { // allow the `mask` parameter to be optional
    cb = mask;
    mask = 0777; // Read and Write permissions
  }
  var fs = require('fs');
  fs.mkdir(path, mask, function(err) {
    if (err) {
      if (err.code == 'EEXIST') {
      	cb(null);
      } // ignore the error if the folder already exists
      else {
        cb(err);
      } // something else went wrong
    } else {
      cb(null);
    } // successfully created folder
  });
};

SequenceDiagram.prototype.filename = function() {
  return self._filename;
}

SequenceDiagram.prototype.setfilename = function(fnOrValue) {
  self._filename = fnOrValue;
}

SequenceDiagram.prototype.filepath = function() {
  return self._filepath;
}

SequenceDiagram.prototype.setfilepath = function(fnOrValue) {
  self._filepath = fnOrValue;
}

SequenceDiagram.prototype.proxies = function() {
  return self._proxies;
}

SequenceDiagram.prototype.setproxies = function(fnOrValue) {
  self._proxies = fnOrValue;
}

module.exports = SequenceDiagram;<|endoftext|>


<commit_before>import {
  addEntityInstances$,
  updateEntities$,
  deleteEntities$,
  duplicateEntities$,
  deleteAllEntities$,
  selectEntities$
   } from '../actions/entityActions'

import logger from '../utils/log'
let log = logger("entities")
log.setLevel("info")

import Rx from 'rx'
let fromEvent = Rx.Observable.fromEvent
let Observable = Rx.Observable
let merge = Rx.Observable.merge

import {generateUUID} from 'usco-kernel2/src/utils'

///defaults, what else ?
const defaults = {
  instances:[],
  selectedIds:[],

  //secondary storage of instances, for (flat) faster/simpler access
  byId:{}
}

/*
const partTemplate = {
      name: "",
      iuid: generateUUID(),
      typeUid: undefined,
      color: "#07a9ff",
      pos: [
          0,
          0,
          0,
      ],
      rot: [
          0,
          0,
          0
      ],
      sca: [
          1,
          1,
          1
      ],
      bbox:{
        min:[0,0,0],
        max:[0,0,0]
      }
  }*/

///helper methods

//////

function makeModification$(intent){

  /*TODO: implement*/
  /*let addEntityInstanceTo$ = intent.addEntityInstanceTo$
    ( instance , parent){
    let parent = parent || null

  }*/

  let _createEntityInstance$ = intent.createEntityInstance$
    .map((data) => (entitiesData) => {

      let h = data.bbox.max[2]  - data.bbox.min[2]

        let partInstance =
        {
            name: data.name,
            iuid: generateUUID(),
            typeUid: data.typeUid,
            color: "#07a9ff",
            pos: [
                0,
                0,
                h/2
            ],
            rot: [
                0,
                0,
                0
            ],
            sca: [
                1,
                1,
                1
            ],
            bbox:data.bbox
        }

    })

  /*add a new entity instance*/
  let _addEntities$ = intent.addEntities$
    //splice in settings
    .combineLatest(intent.settings$,function(data,settings){
      return {nentities:data,settings}
    })
    .map(({nentities,settings}) => (entitiesData) => {
      log.info("adding entity instance(s)", nentities)

      let entities = nentities || []
      if(entities.constructor !== Array) entities = [entities]

      entitiesData.instances = entitiesData.instances.concat(entities)
      let entityIds = entities.map( function(entity) {
        entitiesData.byId[entity.iuid] = entity
        return entity.iuid
      })

      //set selections, if need be
      if(settings.autoSelectNewEntities){
        selectEntities$( entitiesData.instances.map(i=>i.iuid) )
      }

      return entitiesData
    })

  /*set entites properties*/
  let _updateEntities$ = intent.updateEntities$
    .debounce(3)
    .map((nData) => (entitiesData) => {
      log.info("updating entities with data", nData)

      //FIXME , immutable
      let newData = nData || []
      if(newData.constructor !== Array) newData = [newData]

      let outputData = Object.assign({},entitiesData)
      if(!newData) return outputData

      let byId = outputData.byId

      newData.map(function(entry){
        let iuid = entry.iuids
        if(!iuid){
          return undefined
        }
        let tgtEntity    =  Object.assign({}, byId[iuid] )
        if(!tgtEntity){
          return undefined
        }

        for(let key in entry){
          tgtEntity[key] = entry[key]
        }

        //why is this even needed ?
        delete byId[iuid]
        outputData.instances = outputData.instances.filter(inst => inst.iuid !== iuid)

        outputData.instances.push( tgtEntity)
        outputData.byId[iuid] = tgtEntity
      })

      return outputData
    })

  /*remove an entity : it actually only
  removes it from the active assembly*/
  let _deleteEntities$ = intent.deleteEntities$
    .map((remEntitites) => (entitiesData) => {
      log.info("removing entities ", remEntitites)

      //alternative, using the currently selected entities ?
      //entitiesData.

      //FIXME: not sure...., duplication of the above again
      let nEntities  =  entitiesData.instances
      let _tmp = remEntitites.map(entity=>entity.iuid)
      let outNEntities = nEntities.filter(function(entity){ return _tmp.indexOf(entity.iuid)===-1})

      entitiesData.instances = outNEntities

      remEntitites.map(entity=>{ delete entitiesData.byId[entity.iuid] })

      //set selections
      entitiesData.selectedIds = []

      return entitiesData
    })

  /*delete all entities from current entities*/
  let _deleteAllEntities$ = intent.deleteAllEntities$
    .map(() => (entitiesData) => {
      entitiesData.instances = []
      entitiesData.byId = {}
      //set selections
      entitiesData.selectedIds = []
      return entitiesData
    })

  /*create duplicates of given entities*/
  let _duplicateEntities$  = intent.duplicateEntities$
    //splice in settings
    .combineLatest(intent.settings$,function(data,settings){
      return {sources:data,settings}
    })
    .map(({sources,settings}) => (entitiesData) => {
      log.info("duplicating entity instances", sources)
      let dupes = []

      function duplicate(original){
        let doNotCopy = ["iuid","name"]
        let onlyCopy = ["pos","rot","sca","color","typeUid"]

        let dupe = {
          iuid:generateUUID()
        }
        for(let key in original ){
          if( onlyCopy.indexOf( key ) > -1 ){
            dupe[key] = JSON.parse(JSON.stringify(original[key])) //Object.assign([], originalEntity[key] )
          }
        }
        //FIXME : needs to work with all entity types
        //dupe.typeName + "" + ( this.partRegistry.partTypeInstances[ dupe.typeUid ].length - 1)
        dupe.name = original.name + "" //+ ( this.partRegistry.partTypeInstances[ dupe.typeUid ].length - 1)
        return dupe
      }
      dupes = sources.map(duplicate)

      entitiesData.instances = entitiesData.instances.concat(dupes)

      dupes.map(function(dupe){
        entitiesData.byId[dupe.iuid] = dupe
      })

      //set selections, if need be
      if(settings.autoSelectNewEntities) selectEntities$( entitiesData.instances.map(i=>i.iuid) )

      return entitiesData
    })

  /*select given entities*/
  let _selectEntities$ = intent.selectEntities$
    .distinctUntilChanged()//we do not want to be notified multiple times in a row for the same selections
    .map((sentityIds) => (entitiesData) => {
      //log.info("selecting entitites",sentities)

      let entityIds = sentityIds || []
      if(entityIds.constructor !== Array) entityIds = [entityIds]

      //let ids = entities.map( entity => entity.iuid)

      ////TODO: should it be serialized in history ?
      entitiesData.selectedIds = entityIds
      return entitiesData
    })

  /*technically same as deleteAll , but kept seperate for clarity*/
  let _resetEntities$ = intent.newDesign$
    .map((sentities) => (entitiesData) => {
      entitiesData.instances = []
      entitiesData.byId = {}
      //set selections
      entitiesData.selectedIds = []
      return entitiesData
    })

  /*let bla$ = intent.loadDesign$
    .map((sentities) => (entitiesData) => {
      console.log("testing")
      return entitiesData
    })*/

  return merge(
    _addEntities$,
    _updateEntities$,
    _deleteEntities$,
    _deleteAllEntities$,
    _duplicateEntities$,

    _createEntityInstance$,
    _resetEntities$,

    //selection "state" is different
    _selectEntities$
  )
}

function model(intent, source) {
  let source$ = source || Observable.just(defaults)

  let modification$ = makeModification$(intent)

  return modification$
    .merge(source$)
    .scan((entityData, modFn) => modFn(entityData))//combine existing data with new one
    //.distinctUntilChanged()
    .shareReplay(1)
}

export default model

 //just an idea: for context menu etc
/*let availableActions = {
  "select"   :selectEntities$,
  "delete"   :deleteEntities$,
  "deleteAll":deleteAllEntities$,
  "duplicate":duplicateEntities$
}

export {availableActions}*/<commit_msg>- fixed bug that would add entities whenever the settings$ observable changed (withLatestFrom vs combineLatest)<commit_after>import {
  addEntityInstances$,
  updateEntities$,
  deleteEntities$,
  duplicateEntities$,
  deleteAllEntities$,
  selectEntities$
   } from '../actions/entityActions'

import logger from '../utils/log'
let log = logger("entities")
log.setLevel("info")

import Rx from 'rx'
let fromEvent = Rx.Observable.fromEvent
let Observable = Rx.Observable
let merge = Rx.Observable.merge

import {generateUUID} from 'usco-kernel2/src/utils'

///defaults, what else ?
const defaults = {
  instances:[],
  selectedIds:[],

  //secondary storage of instances, for (flat) faster/simpler access
  byId:{}
}

/*
const partTemplate = {
      name: "",
      iuid: generateUUID(),
      typeUid: undefined,
      color: "#07a9ff",
      pos: [
          0,
          0,
          0,
      ],
      rot: [
          0,
          0,
          0
      ],
      sca: [
          1,
          1,
          1
      ],
      bbox:{
        min:[0,0,0],
        max:[0,0,0]
      }
  }*/

///helper methods

//////

function makeModification$(intent){

  /*TODO: implement*/
  /*let addEntityInstanceTo$ = intent.addEntityInstanceTo$
    ( instance , parent){
    let parent = parent || null

  }*/

  let _createEntityInstance$ = intent.createEntityInstance$
    .map((data) => (entitiesData) => {

      let h = data.bbox.max[2]  - data.bbox.min[2]

        let partInstance =
        {
            name: data.name,
            iuid: generateUUID(),
            typeUid: data.typeUid,
            color: "#07a9ff",
            pos: [
                0,
                0,
                h/2
            ],
            rot: [
                0,
                0,
                0
            ],
            sca: [
                1,
                1,
                1
            ],
            bbox:data.bbox
        }

    })

  /*add a new entity instance*/
  let _addEntities$ = intent.addEntities$
    //splice in settings
    .withLatestFrom(intent.settings$,function(data,settings){
      return {nentities:data,settings}
    })
    .map(({nentities,settings}) => (entitiesData) => {
      log.info("adding entity instance(s)", nentities)

      let entities = nentities || []
      if(entities.constructor !== Array) entities = [entities]

      entitiesData.instances = entitiesData.instances.concat(entities)
      let entityIds = entities.map( function(entity) {
        entitiesData.byId[entity.iuid] = entity
        return entity.iuid
      })

      //set selections, if need be
      if(settings.autoSelectNewEntities){
        selectEntities$( entitiesData.instances.map(i=>i.iuid) )
      }

      return entitiesData
    })

  /*set entites properties*/
  let _updateEntities$ = intent.updateEntities$
    .debounce(3)
    .map((nData) => (entitiesData) => {
      log.info("updating entities with data", nData)

      //FIXME , immutable
      let newData = nData || []
      if(newData.constructor !== Array) newData = [newData]

      let outputData = Object.assign({},entitiesData)
      if(!newData) return outputData

      let byId = outputData.byId

      newData.map(function(entry){
        let iuid = entry.iuids
        if(!iuid){
          return undefined
        }
        let tgtEntity    =  Object.assign({}, byId[iuid] )
        if(!tgtEntity){
          return undefined
        }

        for(let key in entry){
          tgtEntity[key] = entry[key]
        }

        //why is this even needed ?
        delete byId[iuid]
        outputData.instances = outputData.instances.filter(inst => inst.iuid !== iuid)

        outputData.instances.push( tgtEntity)
        outputData.byId[iuid] = tgtEntity
      })

      return outputData
    })

  /*remove an entity : it actually only
  removes it from the active assembly*/
  let _deleteEntities$ = intent.deleteEntities$
    .map((remEntitites) => (entitiesData) => {
      log.info("removing entities ", remEntitites)

      //alternative, using the currently selected entities ?
      //entitiesData.

      //FIXME: not sure...., duplication of the above again
      let nEntities  =  entitiesData.instances
      let _tmp = remEntitites.map(entity=>entity.iuid)
      let outNEntities = nEntities.filter(function(entity){ return _tmp.indexOf(entity.iuid)===-1})

      entitiesData.instances = outNEntities

      remEntitites.map(entity=>{ delete entitiesData.byId[entity.iuid] })

      //set selections
      entitiesData.selectedIds = []

      return entitiesData
    })

  /*delete all entities from current entities*/
  let _deleteAllEntities$ = intent.deleteAllEntities$
    .map(() => (entitiesData) => {
      entitiesData.instances = []
      entitiesData.byId = {}
      //set selections
      entitiesData.selectedIds = []
      return entitiesData
    })

  /*create duplicates of given entities*/
  let _duplicateEntities$  = intent.duplicateEntities$
    //splice in settings
    .withLatestFrom(intent.settings$,function(data,settings){
      return {sources:data,settings}
    })
    .map(({sources,settings}) => (entitiesData) => {
      log.info("duplicating entity instances", sources)
      let dupes = []

      function duplicate(original){
        let doNotCopy = ["iuid","name"]
        let onlyCopy = ["pos","rot","sca","color","typeUid"]

        let dupe = {
          iuid:generateUUID()
        }
        for(let key in original ){
          if( onlyCopy.indexOf( key ) > -1 ){
            dupe[key] = JSON.parse(JSON.stringify(original[key])) //Object.assign([], originalEntity[key] )
          }
        }
        //FIXME : needs to work with all entity types
        //dupe.typeName + "" + ( this.partRegistry.partTypeInstances[ dupe.typeUid ].length - 1)
        dupe.name = original.name + "" //+ ( this.partRegistry.partTypeInstances[ dupe.typeUid ].length - 1)
        return dupe
      }
      dupes = sources.map(duplicate)

      entitiesData.instances = entitiesData.instances.concat(dupes)

      dupes.map(function(dupe){
        entitiesData.byId[dupe.iuid] = dupe
      })

      //set selections, if need be
      if(settings.autoSelectNewEntities) selectEntities$( entitiesData.instances.map(i=>i.iuid) )

      return entitiesData
    })

  /*select given entities*/
  let _selectEntities$ = intent.selectEntities$
    .distinctUntilChanged()//we do not want to be notified multiple times in a row for the same selections
    .map((sentityIds) => (entitiesData) => {
      //log.info("selecting entitites",sentities)

      let entityIds = sentityIds || []
      if(entityIds.constructor !== Array) entityIds = [entityIds]

      //let ids = entities.map( entity => entity.iuid)

      ////TODO: should it be serialized in history ?
      entitiesData.selectedIds = entityIds
      return entitiesData
    })

  /*technically same as deleteAll , but kept seperate for clarity*/
  let _resetEntities$ = intent.newDesign$
    .map((sentities) => (entitiesData) => {
      entitiesData.instances = []
      entitiesData.byId = {}
      //set selections
      entitiesData.selectedIds = []
      return entitiesData
    })

  /*let bla$ = intent.loadDesign$
    .map((sentities) => (entitiesData) => {
      console.log("testing")
      return entitiesData
    })*/

  return merge(
    _addEntities$,
    _updateEntities$,
    _deleteEntities$,
    _deleteAllEntities$,
    _duplicateEntities$,

    _createEntityInstance$,
    _resetEntities$,

    //selection "state" is different
    _selectEntities$
  )
}

function model(intent, source) {
  let source$ = source || Observable.just(defaults)

  intent.selectEntities$ = intent.selectEntities$.merge(selectEntities$)

  let modification$ = makeModification$(intent)

  return modification$
    .merge(source$)
    .scan((entityData, modFn) => modFn(entityData))//combine existing data with new one
    //.distinctUntilChanged()
    .shareReplay(1)
}

export default model

 //just an idea: for context menu etc
/*let availableActions = {
  "select"   :selectEntities$,
  "delete"   :deleteEntities$,
  "deleteAll":deleteAllEntities$,
  "duplicate":duplicateEntities$
}

export {availableActions}*/<|endoftext|>


<commit_before>describe('nbNotebook directive', function(){
  var compile;
  var scope;
  var element;
  var httpBackend;
  var isolateScope;

  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));
  beforeEach(module('oide.templates'));
  beforeEach(module('oide.nbterm'));
  beforeEach(module('oide.filesystemservice'));
  // beforeEach(module('/static/nbterm/templates/notebook.html'));

  beforeEach(inject(function($rootScope, $compile, $httpBackend){
    compile = $compile;
    scope = $rootScope.$new();

    httpBackend = $httpBackend;

    var el = angular.element('

');
    element = $compile(el)(scope);
    scope.$digest();
    isolateScope = element.isolateScope();
  }));

  describe('notebook tests', function(){
    it('directive should be initialized', function(){
      // Expect cells to be defined
      expect(isolateScope).toBeDefined();
      // Expect cells array length to be 1
      expect(isolateScope.cells.length).toBe(1);
      // Expect the kernel name to bash
      expect(isolateScope.kernelName).toBe("bash");
      // Expect runQueue to be defined
      expect(isolateScope.runQueue).toBeDefined();
      expect(isolateScope.runQueue.length).toBe(0);
    });

    it('should insert a cell above', function(){
      var cell = isolateScope.cells[0];
      var oldIndex = isolateScope.cells.indexOf(cell);
      isolateScope.insertCellAbove(cell);
      var newIndex = isolateScope.cells.indexOf(cell);
      // Expect length of cells array to be 2
      expect(isolateScope.cells.length).toBe(2);
      // Expect new index to be 1 more than old index
      expect(newIndex).toBe(oldIndex + 1);
    });

    it('should insert a cell below', function(){
      var cell = isolateScope.cells[0];
      var oldIndex = isolateScope.cells.indexOf(cell);
      isolateScope.insertCellBelow(cell);
      var newIndex = isolateScope.cells.indexOf(cell);
      // Expect length of cells to be 2
      expect(isolateScope.cells.length).toBe(2);
      // Expect new index and old index to be the same
      expect(newIndex).toBe(oldIndex);
    });

    it('should delete a cell when there is only one cell', function(){
      var cell = isolateScope.cells[0];
      isolateScope.deleteCell(cell);
      expect(isolateScope.cells.length).toBe(0);
    });

    it('should delete a cell when there is more than one cell, and inserted below', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellBelow(cell);
      isolateScope.deleteCell(cell);
      // Cell count should be 1
      expect(isolateScope.cells.length).toBe(1);
      // The cell should not be present in cells array
      expect(isolateScope.cells.indexOf(cell)).toBe(-1);
    });

    it('should delete a cell when there is more than one cell, and inserted above', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellAbove(cell);
      isolateScope.deleteCell(cell);
      // Cell count should be 1
      expect(isolateScope.cells.length).toBe(1);
      // The cell should not be present in cells array
      expect(isolateScope.cells.indexOf(cell)).toBe(-1);
    });

    it('should be able to run a cell', function(){
      var cell = isolateScope.cells[0];
      isolateScope.runCell(cell);
      // expect statements
      expect(cell.hasExecuted).not.toBeTruthy();
      expect(cell.running).toBeTruthy();
      expect(cell.showOutput).toBeTruthy();
      expect(isolateScope.runQueue.length).toBe(1);
    });
    it('should be able to run all the cells above', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellBelow(cell);
      isolateScope.insertCellBelow(cell);
      isolateScope.insertCellAbove(cell);
      isolateScope.insertCellAbove(cell);
      isolateScope.runAllCellsAbove(isolateScope.cells[4]);
      // Expect runqueue to have 4 cells
      expect(isolateScope.runQueue.length).toBe(4);
    });
  });

});
<commit_msg>test $watchCollection on cells<commit_after>describe('nbNotebook directive', function(){
  var compile;
  var scope;
  var element;
  var httpBackend;
  var isolateScope;

  beforeEach(module('oide'));
  beforeEach(module('oide.editor'));
  beforeEach(module('oide.templates'));
  beforeEach(module('oide.nbterm'));
  beforeEach(module('oide.filesystemservice'));
  // beforeEach(module('/static/nbterm/templates/notebook.html'));

  beforeEach(inject(function($rootScope, $compile, $httpBackend){
    compile = $compile;
    scope = $rootScope.$new();

    httpBackend = $httpBackend;

    var el = angular.element('

');
    element = $compile(el)(scope);
    scope.$digest();
    isolateScope = element.isolateScope();
  }));

  describe('notebook tests', function(){
    it('directive should be initialized', function(){
      // Expect cells to be defined
      expect(isolateScope).toBeDefined();
      // Expect cells array length to be 1
      expect(isolateScope.cells.length).toBe(1);
      // Expect the kernel name to bash
      expect(isolateScope.kernelName).toBe("bash");
      // Expect runQueue to be defined
      expect(isolateScope.runQueue).toBeDefined();
      expect(isolateScope.runQueue.length).toBe(0);
    });

    it('should insert a cell above', function(){
      var cell = isolateScope.cells[0];
      var oldIndex = isolateScope.cells.indexOf(cell);
      isolateScope.insertCellAbove(cell);
      var newIndex = isolateScope.cells.indexOf(cell);
      // Expect length of cells array to be 2
      expect(isolateScope.cells.length).toBe(2);
      // Expect new index to be 1 more than old index
      expect(newIndex).toBe(oldIndex + 1);
    });

    it('should insert a cell below', function(){
      var cell = isolateScope.cells[0];
      var oldIndex = isolateScope.cells.indexOf(cell);
      isolateScope.insertCellBelow(cell);
      var newIndex = isolateScope.cells.indexOf(cell);
      // Expect length of cells to be 2
      expect(isolateScope.cells.length).toBe(2);
      // Expect new index and old index to be the same
      expect(newIndex).toBe(oldIndex);
    });

    it('should delete a cell when there is only one cell', function(){
      var cell = isolateScope.cells[0];
      isolateScope.deleteCell(cell);
      expect(isolateScope.cells.length).toBe(0);
    });

    it('should delete a cell when there is more than one cell, and inserted below', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellBelow(cell);
      isolateScope.deleteCell(cell);
      // Cell count should be 1
      expect(isolateScope.cells.length).toBe(1);
      // The cell should not be present in cells array
      expect(isolateScope.cells.indexOf(cell)).toBe(-1);
    });

    it('should delete a cell when there is more than one cell, and inserted above', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellAbove(cell);
      isolateScope.deleteCell(cell);
      // Cell count should be 1
      expect(isolateScope.cells.length).toBe(1);
      // The cell should not be present in cells array
      expect(isolateScope.cells.indexOf(cell)).toBe(-1);
    });

    it('should be able to run a cell', function(){
      var cell = isolateScope.cells[0];
      isolateScope.runCell(cell);
      // expect statements
      expect(cell.hasExecuted).not.toBeTruthy();
      expect(cell.running).toBeTruthy();
      expect(cell.showOutput).toBeTruthy();
      expect(isolateScope.runQueue.length).toBe(1);
    });
    it('should be able to run all the cells above', function(){
      var cell = isolateScope.cells[0];
      isolateScope.insertCellBelow(cell);
      isolateScope.insertCellBelow(cell);
      isolateScope.insertCellAbove(cell);
      isolateScope.insertCellAbove(cell);
      isolateScope.runAllCellsAbove(isolateScope.cells[4]);
      // Expect runqueue to have 4 cells
      expect(isolateScope.runQueue.length).toBe(4);
    });
    it('should create a new cell when the length of cells array becomes zero', function(){
      var cell = isolateScope.cells[0];
      isolateScope.deleteCell(cell);
      expect(isolateScope.cells.length).toBe(0);
      isolateScope.$digest();
      // It should create a new cell
      expect(isolateScope.cells.length).toBe(1);
    });
  });

});
<|endoftext|>


<commit_before>import chunkify from '../index'
import ChunkifyOptions from '../options'
import _ from 'underscore'

const USAGE = 'Usage: chunkify.interval(Function fn, Number final, [Object options])';

let ok_usage = (fn, final, options) => {
  if (!_.isFunction(fn)) {
    throw new Error(`${USAGE} - bad fn; not a function`);
  } else  if (!_.isNumber(final)) {
    throw new Error(`${USAGE} - bad final; not a number`);
  }
  let {start} = options;
  if (start != null) {
    if (!_.isNumber(start)) {
      throw new Error(`${USAGE} - bad start; not a number`);
    } else if (start > final) {
      throw new Error(`${USAGE} - bad start; it's greater than final`);
    }
  }
};

let interval = (fn, final, options = {}) => {
  ok_usage(fn, final, options);
  let {scope, chunk, delay} = ChunkifyOptions.of(options);
  let iterator = chunkify.generator({
    start: options.start || 0,
    final,
    chunk,
    delay
  });
  var process_chunk_sync = (resolve, reject) => {
    let next = iterator.next();
    while (!(next.value instanceof Promise) && !next.done) {
      try {
        fn.call(scope, next.value)
      } catch (error) {
        return reject({error, index: next.value});
      }
      next = iterator.next();
    }
    if (next.done) {
      return resolve();
    }
    return next.value.then(() => {
      return process_chunk_sync(resolve, reject)
    });
  };
  return new Promise(process_chunk_sync);
};

export default interval<commit_msg>cleaning<commit_after>import chunkify from '../index'
import ChunkifyOptions from '../options'
import _ from 'underscore'

const USAGE = 'Usage: chunkify.interval(Function fn, Number final, [Object options])';

let ok_usage = (fn, final, options) => {
  if (!_.isFunction(fn)) {
    throw new Error(`${USAGE} - bad fn; not a function`);
  } else  if (!_.isNumber(final)) {
    throw new Error(`${USAGE} - bad final; not a number`);
  }
  let {start} = options;
  if (start != null) {
    if (!_.isNumber(start)) {
      throw new Error(`${USAGE} - bad start; not a number`);
    } else if (start > final) {
      throw new Error(`${USAGE} - bad start; it's greater than final`);
    }
  }
};

let interval = (fn, final, options = {}) => {
  ok_usage(fn, final, options);
  let {start} = _.defaults(options, {start: 0});
  let okoptions = ChunkifyOptions.of(options);
  let generator = chunkify.generator(start, final, okoptions);
  var process_chunk_sync = (resolve, reject) => {
    let next = generator.next();
    while (!(next.value instanceof Promise) && !next.done) {
      try {
        fn.call(okoptions.scope, next.value)
      } catch (error) {
        return reject({error, index: next.value});
      }
      next = generator.next();
    }
    if (next.done) {
      return resolve();
    }
    return next.value.then(() => {
      return process_chunk_sync(resolve, reject)
    });
  };
  return new Promise(process_chunk_sync);
};

export default interval<|endoftext|>


<commit_before>module.exports = (client, message, args) => {

    /*let member = message.mentions.members.first();
    if(!member){
      return message.reply("Please mention a valid member of this server");

    }else{

    let embed = new DynamicsCompressorNode.RichEmbed()

        message.reply(message.author.avatarURL);
        .setAuthor(member.user.username)
        .setDescription("Informação do usuário!")
        .setColor("#9B59B6")
        .setField("Nome", member.user.tag)
        .addField("ID", member.user.id)
        .addField("Criado em", member.user.createdAt);

        message.channel.sendEmbed(embed);

        return;  }*/

        let member = message.mentions.members.first();
    if(!member){
      return message.reply("Por favor digite um nome válido!");

    }else{

        message.reply(message.author.avatar);
        message.reply(member.user.username);
        message.reply("Informação do usuário!");
        message.reply("Nome", member.user.tag);
        message.reply("ID", member.user.id);
        message.reply("Criado em", member.user.createdAt);

          }

};<commit_msg><commit_after>module.exports = (client, message, args) => {

    /*let member = message.mentions.members.first();
    if(!member){
      return message.reply("Please mention a valid member of this server");

    }else{

    let embed = new DynamicsCompressorNode.RichEmbed()

        message.reply(message.author.avatarURL);
        .setAuthor(member.user.username)
        .setDescription("Informação do usuário!")
        .setColor("#9B59B6")
        .setField("Nome", member.user.tag)
        .addField("ID", member.user.id)
        .addField("Criado em", member.user.createdAt);

        message.channel.sendEmbed(embed);

        return;  }*/

        let member = message.mentions.members.first();
    if(!member){
      return message.reply("Por favor digite um nome válido!");

    }else{

        message.reply(message.author.avatar);

          }

};<|endoftext|>


<commit_before><commit_msg>Double prop<commit_after><|endoftext|>


<commit_before>import React, { useRef } from 'react';
import { Box, NumericInput } from '../../';
import theme from './theme.css';

const transformToPaddedNumber = (number) => (number < 10 ? `0${number}` : number.toString());

const DurationInput = ({ value, onChange, onBlur, onFocus, onKeyDown, autoFocus, className }) => {
  const ref = useRef();

  const handleHoursChanged = (_, hours) => {
    if (!onChange) {
      return;
    }

    if (hours === '') {
      onChange({
        minutes: value?.minutes,
      });
    }

    const parsedHours = parseInt(hours);
    if (!Number.isInteger(parsedHours)) {
      return;
    }

    onChange({
      ...value,
      hours: parsedHours,
    });
  };

  const handleMinutesChange = (_, minutes) => {
    if (!onChange) {
      return;
    }

    if (minutes === '') {
      onChange({
        hours: value?.hours,
      });
      return;
    }

    const parsedMinutes = parseInt(minutes);
    if (!Number.isInteger(parsedMinutes)) {
      return;
    }

    if (parsedMinutes >= 60) {
      onChange({
        hours: (value?.hours || 0) + 1,
        minutes: 0,
      });
      return;
    }

    if (parsedMinutes < 0) {
      onChange({
        hours: (value?.hours || 1) - 1,
        minutes: 59,
      });
      return;
    }

    onChange({
      ...value,
      minutes: parsedMinutes,
    });
  };

  /**
   * This blur handler is a special one, because this input consists of multiple focus points:
   * the two inputs themselves, and the four increment/decrement buttons
   * we filter out the blur events caused by changing focus between these, so the onBlur event only
   * gets triggered when really blurring outside of the entire component
   */
  const handleBlur = (event) => {
    if (!event.relatedTarget) {
      onBlur && onBlur(event);
      return;
    }

    const inputs = ref.current?.getElementsByTagName('input') || [];
    if (Array.from(inputs).find((node) => node === event.relatedTarget)) {
      return;
    }

    const buttons = ref.current?.getElementsByTagName('button') || [];
    if (Array.from(buttons).find((node) => node === event.relatedTarget)) {
      return;
    }

    onBlur && onBlur(event);
  };

  let minutes = value?.minutes;
  if (Number.isInteger(minutes)) {
    minutes = transformToPaddedNumber(minutes);
  }

  return (
    <Box display="flex" alignItems="center" ref={ref} className={className}>
      <NumericInput
        placeholder="0"
        min={0}
        value={value?.hours ?? ''}
        onChange={handleHoursChanged}
        onBlur={handleBlur}
        onFocus={onFocus}
        onKeyDown={onKeyDown}
        type="text"
        inputMode="numeric"
        flexGrow={1}
        className={theme['duration-input-numeric-input']}
        autoFocus={autoFocus}
      />
      <Box element="span" className={theme['duration-input-colon']}>
        :
      </Box>
      <NumericInput
        placeholder="00"
        {...(!value?.hours ? { min: 0 } : {})}
        value={minutes ?? ''}
        onChange={handleMinutesChange}
        onBlur={handleBlur}
        onFocus={onFocus}
        onKeyDown={onKeyDown}
        type="text"
        inputMode="numeric"
        flexGrow={1}
        className={theme['duration-input-numeric-input']}
      />
    </Box>
  );
};

export default DurationInput;
<commit_msg>:lipstick: lighten the color of the colon<commit_after>import React, { useRef } from 'react';
import { Box, NumericInput, TextBodyCompact } from '../../';
import theme from './theme.css';

const transformToPaddedNumber = (number) => (number < 10 ? `0${number}` : number.toString());

const DurationInput = ({ value, onChange, onBlur, onFocus, onKeyDown, autoFocus, className }) => {
  const ref = useRef();

  const handleHoursChanged = (_, hours) => {
    if (!onChange) {
      return;
    }

    if (hours === '') {
      onChange({
        minutes: value?.minutes,
      });
    }

    const parsedHours = parseInt(hours);
    if (!Number.isInteger(parsedHours)) {
      return;
    }

    onChange({
      ...value,
      hours: parsedHours,
    });
  };

  const handleMinutesChange = (_, minutes) => {
    if (!onChange) {
      return;
    }

    if (minutes === '') {
      onChange({
        hours: value?.hours,
      });
      return;
    }

    const parsedMinutes = parseInt(minutes);
    if (!Number.isInteger(parsedMinutes)) {
      return;
    }

    if (parsedMinutes >= 60) {
      onChange({
        hours: (value?.hours || 0) + 1,
        minutes: 0,
      });
      return;
    }

    if (parsedMinutes < 0) {
      onChange({
        hours: (value?.hours || 1) - 1,
        minutes: 59,
      });
      return;
    }

    onChange({
      ...value,
      minutes: parsedMinutes,
    });
  };

  /**
   * This blur handler is a special one, because this input consists of multiple focus points:
   * the two inputs themselves, and the four increment/decrement buttons
   * we filter out the blur events caused by changing focus between these, so the onBlur event only
   * gets triggered when really blurring outside of the entire component
   */
  const handleBlur = (event) => {
    if (!event.relatedTarget) {
      onBlur && onBlur(event);
      return;
    }

    const inputs = ref.current?.getElementsByTagName('input') || [];
    if (Array.from(inputs).find((node) => node === event.relatedTarget)) {
      return;
    }

    const buttons = ref.current?.getElementsByTagName('button') || [];
    if (Array.from(buttons).find((node) => node === event.relatedTarget)) {
      return;
    }

    onBlur && onBlur(event);
  };

  let minutes = value?.minutes;
  if (Number.isInteger(minutes)) {
    minutes = transformToPaddedNumber(minutes);
  }

  return (
    <Box display="flex" alignItems="center" ref={ref} className={className}>
      <NumericInput
        placeholder="0"
        min={0}
        value={value?.hours ?? ''}
        onChange={handleHoursChanged}
        onBlur={handleBlur}
        onFocus={onFocus}
        onKeyDown={onKeyDown}
        type="text"
        inputMode="numeric"
        flexGrow={1}
        className={theme['duration-input-numeric-input']}
        autoFocus={autoFocus}
      />
      <TextBodyCompact color="neutral" tint="darkest" className={theme['duration-input-colon']}>
        :
      </TextBodyCompact>
      <NumericInput
        placeholder="00"
        {...(!value?.hours ? { min: 0 } : {})}
        value={minutes ?? ''}
        onChange={handleMinutesChange}
        onBlur={handleBlur}
        onFocus={onFocus}
        onKeyDown={onKeyDown}
        type="text"
        inputMode="numeric"
        flexGrow={1}
        className={theme['duration-input-numeric-input']}
      />
    </Box>
  );
};

export default DurationInput;
<|endoftext|>


<commit_before>var test = require('tape')
var mongojs = require('../')

test('connect non existing db', function (t) {
  var db = mongojs('mongodb://1.0.0.1:23/aiguillage?connectTimeoutMS=100', ['a'])

  db.runCommand({ping: 1}, function (err) {
    t.ok(err, 'Should yield an error if non connection to db could be established')

    db.runCommand({ping: 1}, function (err) {
      t.ok(err, 'Should yield an error if non connection to db could be established')

      t.end()
    })
  })
})
<commit_msg>Add a connection error handler<commit_after>var test = require('tape')
var mongojs = require('../')

test('connect non existing db', function (t) {
  var db = mongojs('mongodb://1.0.0.1:23/aiguillage?connectTimeoutMS=100', ['a'])
  db.on('error', console.log)

  db.runCommand({ping: 1}, function (err) {
    t.ok(err, 'Should yield an error if non connection to db could be established')

    db.runCommand({ping: 1}, function (err) {
      t.ok(err, 'Should yield an error if non connection to db could be established')

      t.end()
    })
  })
})
<|endoftext|>


<commit_before>// Modal Image Gallery
function onClick(element) {
    document.getElementById("img01").src = element.src;
    document.getElementById("modal01").style.display = "block";
    var captionText = document.getElementById("caption");
    captionText.innerHTML = element.alt;
}

// Change style of navbar on scroll
window.onscroll = function() {myFunction()};
function myFunction() {
    var navbar = document.getElementById("myNavbar");
    if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
        navbar.className = "w3-bar" + " w3-card-2" + " w3-animate-top" + " w3-white";
    } else {
        navbar.className = navbar.className.replace(" w3-card-2 w3-animate-top w3-white", "");
    }
}

// Used to toggle the menu on small screens when clicking on the menu button
function toggleFunction() {
    var x = document.getElementById("navDemo");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    } else {
        x.className = x.className.replace(" w3-show", "");
    }
}

//connecting scroll to a div class

    var $win = $(window);
    $win.on('scroll', function(s){

    var top = $win.scrollTop();

    top = top - 4300;

    if(top<0)
    $('.contactInfo').css('margin-left',top + 'px');
});

//image scroll
var $win = $(window);
$win.on('scroll', function(s){
  var top = $win.scrollTop();
  top = top/8;
$('.aliMain').css('margin-right',top + 'px');
});

//main text scroll
var $win = $(window);
$win.on('scroll', function(s){
  var top = $win.scrollTop();
  top = top/2;
$('.mainT').css('margin-left',top + 'px');
});

// bounce animation for new link
setInterval(function(){
    $('#laramedia').toggleClass('animated swing');
},1500);
//animating the email
setInterval(function(){
    $('#email').toggleClass('animated swing');
},2000);
//aniamting CV
setInterval(function(){
    $('#cv').toggleClass('animated flash');
},2000);

  var typed = new Typed('#myName', {
    strings: ["Graduate Developer","Ali Kiyan"],
    typeSpeed: 300
  });
  var typed = new Typed('#bio', {
    strings: ["My name is Ali and I am studying my masters ( Databases and Web-Based Systems) as an international student. I am a 22 year old tech fanatic looking for an oppotunity to work and master my skill. Having studied in software engineering in my Bachelor, I can say I have a proper understanding of computer science and software development. I have experience in web development and designed full web sites (front-end and backend with database design). I would like to develop applications and web applications as well."],
    typeSpeed: 30
  });
  var typed = new Typed('#cvT', {
    strings: ["Ali Kiyan CV"],
    typeSpeed: 100
  });

document.querySelectorAll(".typed-cursor")[1].style.display = "none";
document.querySelectorAll(".typed-cursor")[2].style.display = "none";
<commit_msg>disabling contactIngoscrolling horizantal effect<commit_after>// Modal Image Gallery
function onClick(element) {
    document.getElementById("img01").src = element.src;
    document.getElementById("modal01").style.display = "block";
    var captionText = document.getElementById("caption");
    captionText.innerHTML = element.alt;
}

// Change style of navbar on scroll
window.onscroll = function() {myFunction()};
function myFunction() {
    var navbar = document.getElementById("myNavbar");
    if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 100) {
        navbar.className = "w3-bar" + " w3-card-2" + " w3-animate-top" + " w3-white";
    } else {
        navbar.className = navbar.className.replace(" w3-card-2 w3-animate-top w3-white", "");
    }
}

// Used to toggle the menu on small screens when clicking on the menu button
function toggleFunction() {
    var x = document.getElementById("navDemo");
    if (x.className.indexOf("w3-show") == -1) {
        x.className += " w3-show";
    } else {
        x.className = x.className.replace(" w3-show", "");
    }
}

// //connecting scroll to a div class
//
//
//     var $win = $(window);
//     $win.on('scroll', function(s){
//
//     var top = $win.scrollTop();
//
//     top = top - 4300;
//
//     if(top<0)
//     $('.contactInfo').css('margin-left',top + 'px');
// });

//image scroll
var $win = $(window);
$win.on('scroll', function(s){
  var top = $win.scrollTop();
  top = top/8;
$('.aliMain').css('margin-right',top + 'px');
});

//main text scroll
var $win = $(window);
$win.on('scroll', function(s){
  var top = $win.scrollTop();
  top = top/2;
$('.mainT').css('margin-left',top + 'px');
});

// bounce animation for new link
setInterval(function(){
    $('#laramedia').toggleClass('animated swing');
},1500);
//animating the email
setInterval(function(){
    $('#email').toggleClass('animated swing');
},2000);
//aniamting CV
setInterval(function(){
    $('#cv').toggleClass('animated flash');
},2000);

  var typed = new Typed('#myName', {
    strings: ["Graduate Developer","Ali Kiyan"],
    typeSpeed: 300
  });
  var typed = new Typed('#bio', {
    strings: ["My name is Ali and I am studying my masters ( Databases and Web-Based Systems) as an international student. I am a 22 year old tech fanatic looking for an oppotunity to work and master my skill. Having studied in software engineering in my Bachelor, I can say I have a proper understanding of computer science and software development. I have experience in web development and designed full web sites (front-end and backend with database design). I would like to develop applications and web applications as well."],
    typeSpeed: 30
  });
  var typed = new Typed('#cvT', {
    strings: ["Ali Kiyan CV"],
    typeSpeed: 100
  });

document.querySelectorAll(".typed-cursor")[1].style.display = "none";
document.querySelectorAll(".typed-cursor")[2].style.display = "none";
<|endoftext|>


<commit_before>'use strict';

/* author: M@Campbell
 * 10/20/2015
 *
 * Views for any page that needs special controls.
*/

// Parent view for all the page controls.
var ParentPageControlView = Backbone.View.extend({
    /* - initialize()
     * - render()
     * - derender()
     *
     * - loadControls() : Customize this function for each page if you want.
     */
    initialize: function() {
        _.bindAll(this, 'render', 'derender', 'click', 'change');
    },
    events: {
        'click span': 'click',
        'change select': 'change'
    },
    // this template will loop through each of the parameters defined in the
    // instantiaed model and create a <option> tag in the select element with
    // an id of the actual search term.
    template: _.template('<% _.each(params, function(item) { %> <span id="<%= item[0] %>"><%= item[1] %><% }) %>'),
    render: function() {
        if (this.model) { this.$el.html(this.template(this.model.toJSON())); } else
            { this.$el.html(this.template()); }

        // for now, this is in the parent view.  If it doesn't seem to be that common
        // we can move it to a child view's render function.  This is basically
        // just a place holder for additional searching that isn't added to
        // the search bar.
        this.$el.prepend('

');
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off();
    },
    click: function(e) {
        var target = e.target.value;
        if ($('#'+target).hasClass('active')) {
            $('#'+target).removeClass('active');
            $('#hiddenSearch').val('');
        } else {
            $('.active').removeClass('active');
            $('#'+target).toggleClass('active');
            $('#hiddenSearch').val(target);
        }

        // once that array is all sorted out, lets stick it in the hidden search field that
        // has been appended to the page.
        $('#search').trigger('keyup');
    },
    change: function(e) {
        // not implemented
    }
});

var DataCatalogPageControlView = ParentPageControlView.extend({
    events: {
        'change select#search-param': 'click'
    },
    template: JST['ooiui/static/js/partials/DataCatalogPageControlView.html'],
    click: function(e) {
        $('#search').trigger('keyup');
    }
});

var AssetManagementPageControlView = ParentPageControlView.extend({});

var TocPageControlView = ParentPageControlView.extend({
    template: JST['ooiui/static/js/partials/TocPageControlView.html'],
    click: function(e) {
        // simple toggle of DOM elements.
        switch(e.target.id) {
            case 'engToggle':
                $('.eng-item').toggle();
                break;

            case 'metaDataToggle':
                $('.meta-data-item').toggle();
                break;

            case 'refDesToggle':
                $('.ref-des-item').toggle();
                break;
        }

        // toggle the class.
        $('#'+e.target.id).toggleClass('active');
    },
    change: function(e) {
        vent.trigger('toc:paramFilter', e.currentTarget.selectedOptions[0].id);
    },
    render: function(){
        if (this.model) { this.$el.html(this.template(this.model.toJSON())); } else
        { this.$el.html(this.template()); }
        this.$el.prepend('

');
        $('#engToggle').toggleClass('active');
        $('#engToggle').trigger('click');

        return this;
    }
});
<commit_msg>found issue with 'Recovered' and 'Deployed' buttons<commit_after>'use strict';

/* author: M@Campbell
 * 10/20/2015
 *
 * Views for any page that needs special controls.
*/

// Parent view for all the page controls.
var ParentPageControlView = Backbone.View.extend({
    /* - initialize()
     * - render()
     * - derender()
     *
     * - loadControls() : Customize this function for each page if you want.
     */
    initialize: function() {
        _.bindAll(this, 'render', 'derender', 'click', 'change');
    },
    events: {
        'click span': 'click',
        'change select': 'change'
    },
    // this template will loop through each of the parameters defined in the
    // instantiaed model and create a <option> tag in the select element with
    // an id of the actual search term.
    template: _.template('<% _.each(params, function(item) { %> <span id="<%= item[0] %>" value="<%= item[0] %>"><%= item[1] %><% }) %>'),
    render: function() {
        if (this.model) { this.$el.html(this.template(this.model.toJSON())); } else
            { this.$el.html(this.template()); }

        // for now, this is in the parent view.  If it doesn't seem to be that common
        // we can move it to a child view's render function.  This is basically
        // just a place holder for additional searching that isn't added to
        // the search bar.
        this.$el.prepend('

');
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off();
    },
    click: function(e) {
        var target = e.target.value || e.target.id;
        if ($('#'+target).hasClass('active')) {
            $('#'+target).removeClass('active');
            $('#hiddenSearch').val('');
        } else {
            $('.active').removeClass('active');
            $('#'+target).toggleClass('active');
            $('#hiddenSearch').val(target);
        }

        // once that array is all sorted out, lets stick it in the hidden search field that
        // has been appended to the page.
        $('#search').trigger('keyup');
    },
    change: function(e) {
        // not implemented
    }
});

var DataCatalogPageControlView = ParentPageControlView.extend({
    events: {
        'change select#search-param': 'click'
    },
    template: JST['ooiui/static/js/partials/DataCatalogPageControlView.html'],
    click: function(e) {
        $('#search').trigger('keyup');
    }
});

var AssetManagementPageControlView = ParentPageControlView.extend({
});

var TocPageControlView = ParentPageControlView.extend({
    template: JST['ooiui/static/js/partials/TocPageControlView.html'],
    click: function(e) {
        // simple toggle of DOM elements.
        switch(e.target.id) {
            case 'engToggle':
                $('.eng-item').toggle();
                break;

            case 'metaDataToggle':
                $('.meta-data-item').toggle();
                break;

            case 'refDesToggle':
                $('.ref-des-item').toggle();
                break;
        }

        // toggle the class.
        $('#'+e.target.id).toggleClass('active');
    },
    change: function(e) {
        vent.trigger('toc:paramFilter', e.currentTarget.selectedOptions[0].id);
    },
    render: function(){
        if (this.model) { this.$el.html(this.template(this.model.toJSON())); } else
        { this.$el.html(this.template()); }
        this.$el.prepend('

');
        $('#engToggle').toggleClass('active');
        $('#engToggle').trigger('click');

        return this;
    }
});
<|endoftext|>


<commit_before>/* global define */

(() => {
  'use strict';
  let deps = [
    'composer/controls'
  ];
  define('plugins/expiring-uploads/controller', deps, (controls) => {
    var controller = {};
    controller.validateUpload = (response, composer) => {
      let insertText = '[' + response.linkText + '](' + response.url + ') ';
      controls.insertIntoTextarea(composer.textarea, insertText);
    };

    return controller;
  });
})();
<commit_msg>Insert link on success<commit_after>/* global define */

(() => {
  'use strict';
  let deps = [
    'composer/controls'
  ];
  define('plugins/expiring-uploads/controller', deps, (controls) => {
    var controller = {};
    controller.validateUpload = (response, composer) => {
      let selAfterInsert = 0;
      let insertText = '';
      if (composer.selectionStart === composer.selectionEnd) {
        insertText = '[' + response.linkText + '](' + response.url + ')';
        selAfterInsert = composer.selectionEnd + insertText.length;
        controls.insertIntoTextarea(composer.textarea, insertText);
      } else {
        insertText = '](' + response.url + ')';
        selAfterInsert = composer.selectionEnd + response.url.length + 4;
        controls.wrapSelectionInTextareaWith(composer.textarea, '[', insertText);
      }
      /**
       * Modal timeout takes the focus from textarea if set too early
       * https://github.com/nodebb/nodebb/blob/master/public/src/modules/uploader.js#L85-L88
       */
      setTimeout(() => controls.updateTextareaSelection(composer.textarea,
                                                        selAfterInsert,
                                                        selAfterInsert),
                 1000);
    };

    return controller;
  });
})();
<|endoftext|>