<commit_before>"use strict";
/* Test your fear implementation */

var tyf = {

    /** List of available curse words */
    shimpfwoerter: [
        'Du Weichei!',
        'Du Warmd- uscher!',
        'Du Angst- hase!',
        'Du feige Sau!',
        'Du Lulu!',
        'Du Security Freak!',
        'Du Drücke- berger!',
        'Du Wasch- lappen!',
        'Du Becken- rand- schwim- mer!',
        'Du Schisser!',
        'Du fade Nudl!',
        'Du Kakao- trinker!',
        'Du Karusell- bremser!',
        'Du Spielver- derber!',
        'Du Socken- sortierer!'
    ],

    /** Aufgaben die der Nutzer bewältigen darf */
    aufgaben: [
        {
            taskKey: 'aliens',
            befehl: 'Nimm Kontakt mit Aliens auf!',
            details: 'Halte deinen Screen gerade vor dir und bewege ihn mehrmals ehrfurchtsvoll Richtung Himmel.',
            successTitle: 'Yippie!',
            successSubTitle: 'Du hast keine Angst!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir die Antwort der Aliens an.',
            style: 'turkisgelb'
        },
        {
            taskKey: 'scream',
            befehl: 'Schrei so laut du kannst!',
            details: 'Halte deinen Screen gerade vor dir und schrei\' so laut du kannst ins Mikrofon.',
            successTitle: 'Wow!',
            successSubTitle: 'Du kannst schreien!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wie wir schreien.',
            style: 'blaugelb'
        },
        {
            taskKey: 'spin',
            befehl: 'Dreh dich bis du abhebst!',
            details: 'Halte deinen Screen gerade vor dir und dreh\' dich so lange bis du abhebst.',
            successTitle: 'Super!',
            successSubTitle: 'Du bist abgehoben!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an, wann wir abheben.',
            style: 'orangepink'
        },
        {
            taskKey: 'scare',
            befehl: 'Erschrecke deinen Nächsten!',
            details: 'Geh zu der dir nächsten Person, halte deinen Screen vor dein Gesicht, zieh\' ihn plötzlich weg und mach\' eine Grimasse.',
            successTitle: 'Juhu!',
            successSubTitle: 'Du hast jemanden erschreckt!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wie wir uns schrecken.',
            style: 'blaupink'
        },
        {
            taskKey: 'wave',
            befehl: 'Winke einer fremden Person zu!',
            details: 'Halte deinen Screen im Querformat und winke damit einer fremden Person zu.',
            successTitle: 'Wow!',
            successSubTitle: 'Du bist mutig!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wann wir Mut brauchen.',
            style: 'pinkorange'
        }
    ],

    errorOutcome: {
        outcome: 'Oje!',
        sub: 'Du hast dich falsch oder zu wenig bewegt!',
        inst: 'Berühre den Bildschirm um es noch einmal zu versuchen!'
    },

    /** Select a string at random from an array */
    selectRandomFromArray: function (arr) {
        var r = Math.floor(Math.random() * arr.length);
        return arr[r];
    },

    /** Select a curse word at random */
    selectSchimpfwort: function () {
        return this.selectRandomFromArray(this.shimpfwoerter);
    },

    /** This variable holds the currently selected task */
    selectedTask: null,

    /** Select tasks at random */
    selectTask: function() {
        // return this.selectRandomFromArray(this.aufgaben);
        return this.aufgaben[0];
    },

    taskTimeout: null,
    taskInterval: null,

    /** Stop the background jobs */
    clearJobs: function() {
        if(this.taskTimeout) {
            clearTimeout(this.taskTimeout);
        }
        if(this.taskInterval) {
            clearInterval(this.taskInterval);
        }
    },

    /** Select a task and setup the ui */
    setupTask: function(task) {
        this.selectedTask = task;
        $('#anweisung').removeClass('turkisgelb');
        $('#anweisung').removeClass('blaugelb');
        $('#anweisung').removeClass('orangepink');
        $('#anweisung').removeClass('blaupink');
        $('#anweisung').removeClass('pinkorange');
        $('#anweisung').addClass(this.selectedTask.style);
        $('#befehl').html(this.selectedTask.befehl);
        $('#instruktion').html(this.selectedTask.details);

        this.taskTimeout = setTimeout(function() {
            tyf.taskFailed();
        }, 15000);

        this.showSlide('anweisung');
        this.taskInterval = setInterval(function() {
            tyf.executeTask();
        }, 200);
    },

    /** Select a random task and init the UI with it */
    setupRandomTask: function() {
        var t = tyf.selectTask();
        tyf.setupTask(t);
    },

    /** Depending on the task key a certain helper function is called */
    executeTask: function() {
        switch(this.selectedTask.taskKey) {
            case 'aliens': this.executeAlienTask();
        }
    },

    /** Check if the timeseries has a tilting pattern */
    executeAlienTask: function() {
        var found90DegreeGamma;
        var found0DegreeGamma;

        for(var i=0;i<this.orientationData.length;i++) {
            var orientation = this.orientationData[i];
            var gammaAbs = Math.abs(orientation.gamma);
            if(gammaAbs > 70) {
                found90DegreeGamma = orientation.timestamp;
            }
            if(found90DegreeGamma && orientation.timestamp > found90DegreeGamma && orientation.gamma < 20) {
                found0DegreeGamma = orientation.timestamp;
            }
        }

        if(found0DegreeGamma && found90DegreeGamma) {
            this.taskSuccess();
            this.resetOrientationData();
        }
    },

    lastTaskFailed: false,

    /** Switch to the outcome slide and mark it as error */
    taskFailed: function() {
        this.lastTaskFailed = true;
        this.clearJobs();
        $('#outcome').html(this.errorOutcome.outcome);
        $('#outcomesub').html(this.errorOutcome.sub);
        $('#outcomeinst').html(this.errorOutcome.inst);

        $('#ergebnis').removeClass('turkisgelb');
        $('#ergebnis').removeClass('blaugelb');
        $('#ergebnis').removeClass('orangepink');
        $('#ergebnis').removeClass('blaupink');
        $('#ergebnis').removeClass('pinkorange');
        $('#ergebnis').addClass('errorOutcome');

        this.showSlide('ergebnis');
    },

    /** Task was executed correctly */
    taskSuccess: function() {
        this.lastTaskFailed = false;
        this.clearJobs();

        $('#ergebnis').removeClass('turkisgelb');
        $('#ergebnis').removeClass('blaugelb');
        $('#ergebnis').removeClass('orangepink');
        $('#ergebnis').removeClass('blaupink');
        $('#ergebnis').removeClass('pinkorange');
        $('#ergebnis').removeClass('errorOutcome');
        $('#ergebnis').addClass(this.selectedTask.style);

        $('#outcome').html(this.selectedTask.successTitle);
        $('#outcomesub').html(this.selectedTask.successSubTitle);
        $('#outcomeinst').html(this.selectedTask.successTeaser);
        this.showSlide('ergebnis');
    },

    /** Start tracking of device orientation events */
    trackDeviceOrientation: function() {
        if(window.DeviceOrientationEvent) {
            window.addEventListener('deviceorientation', tyf.handleDeviceOrientation, false);
        }else{
            $('#accelStatus').html('Der Bewegunggsensor in deinem Gerät funktioniert leider nicht!');
            $('#accelStatus').show();
        }
    },

    lastOrientationUpdate: null,

    /** Simple ring buffer for orientation data */
    orientationData: [],
    orientationDataInsertPosition: 0,

    /** Handle device orientation event */
    handleDeviceOrientation: function(evt) {
        var now = Date.now();
        if(!tyf.lastOrientationUpdate || now - tyf.lastOrientationUpdate > 200) {
            tyf.lastOrientationUpdate = now;
            $('#orientG').html(evt.gamma.toFixed(3));
            $('#orientB').html(evt.beta.toFixed(3));
            $('#orientA').html(evt.alpha.toFixed(3));
            tyf.orientationData[tyf.orientationDataInsertPosition] = {
                timestamp: now,
                gamma: evt.gamma, beta: evt.beta, alpha: evt.alpha
            };
            tyf.orientationDataInsertPosition = (tyf.orientationDataInsertPosition + 1) % 100;
        }
    },

    /** Clear the orientation data array */
    resetOrientationData: function() {
        tyf.orientationDataInsertPosition = 0;
        tyf.orientationData = [];
    },

    /** If we are on the ergebnis then we need to decide how to handle the click */
    handleErgebnisClick: function() {
        if(this.lastTaskFailed) {
            this.setupRandomTask();
        }else{
            this.showSlide('startscreen');
        }
    },

    /** Show a slide and hide all others */
    showSlide: function (slideId) {
        if (!slideId.startsWith('#')) {
            slideId = '#' + slideId;
        }
        $('.slide').addClass('hidden');
        $(slideId).removeClass('hidden');
    },

    /** Setup the callback handlers for all buttons and slides */
    setupHandlers: function () {
        $('#ichhabeangst').click(function() {
            $('#beschimpfung').html(tyf.selectSchimpfwort());
            tyf.showSlide('schimpfwort');
            setTimeout(function() {
                tyf.showSlide('startscreen');
            }, 3000);
        });
        $('#ichhabekeineangst').click(function () {
            tyf.setupRandomTask();
        });
        $('#ergebnis').click(function () {
            tyf.handleErgebnisClick();
        });
    },

    /** Performs setup of the app and switches to the startscreen afterwards */
	init: function () {
        this.setupHandlers();
        this.trackDeviceOrientation();
        this.showSlide('startscreen');
	}

};

$(document).ready(function() {
	tyf.init();
});
<commit_msg>Reset orientation data before task execution<commit_after>"use strict";
/* Test your fear implementation */

var tyf = {

    /** List of available curse words */
    shimpfwoerter: [
        'Du Weichei!',
        'Du Warmd- uscher!',
        'Du Angst- hase!',
        'Du feige Sau!',
        'Du Lulu!',
        'Du Security Freak!',
        'Du Drücke- berger!',
        'Du Wasch- lappen!',
        'Du Becken- rand- schwim- mer!',
        'Du Schisser!',
        'Du fade Nudl!',
        'Du Kakao- trinker!',
        'Du Karusell- bremser!',
        'Du Spielver- derber!',
        'Du Socken- sortierer!'
    ],

    /** Aufgaben die der Nutzer bewältigen darf */
    aufgaben: [
        {
            taskKey: 'aliens',
            befehl: 'Nimm Kontakt mit Aliens auf!',
            details: 'Halte deinen Screen gerade vor dir und bewege ihn mehrmals ehrfurchtsvoll Richtung Himmel.',
            successTitle: 'Yippie!',
            successSubTitle: 'Du hast keine Angst!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir die Antwort der Aliens an.',
            style: 'turkisgelb'
        },
        {
            taskKey: 'scream',
            befehl: 'Schrei so laut du kannst!',
            details: 'Halte deinen Screen gerade vor dir und schrei\' so laut du kannst ins Mikrofon.',
            successTitle: 'Wow!',
            successSubTitle: 'Du kannst schreien!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wie wir schreien.',
            style: 'blaugelb'
        },
        {
            taskKey: 'spin',
            befehl: 'Dreh dich bis du abhebst!',
            details: 'Halte deinen Screen gerade vor dir und dreh\' dich so lange bis du abhebst.',
            successTitle: 'Super!',
            successSubTitle: 'Du bist abgehoben!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an, wann wir abheben.',
            style: 'orangepink'
        },
        {
            taskKey: 'scare',
            befehl: 'Erschrecke deinen Nächsten!',
            details: 'Geh zu der dir nächsten Person, halte deinen Screen vor dein Gesicht, zieh\' ihn plötzlich weg und mach\' eine Grimasse.',
            successTitle: 'Juhu!',
            successSubTitle: 'Du hast jemanden erschreckt!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wie wir uns schrecken.',
            style: 'blaupink'
        },
        {
            taskKey: 'wave',
            befehl: 'Winke einer fremden Person zu!',
            details: 'Halte deinen Screen im Querformat und winke damit einer fremden Person zu.',
            successTitle: 'Wow!',
            successSubTitle: 'Du bist mutig!',
            successTeaser: 'Berühre den Bildschirm und schau\' dir an wann wir Mut brauchen.',
            style: 'pinkorange'
        }
    ],

    errorOutcome: {
        outcome: 'Oje!',
        sub: 'Du hast dich falsch oder zu wenig bewegt!',
        inst: 'Berühre den Bildschirm um es noch einmal zu versuchen!'
    },

    /** Select a string at random from an array */
    selectRandomFromArray: function (arr) {
        var r = Math.floor(Math.random() * arr.length);
        return arr[r];
    },

    /** Select a curse word at random */
    selectSchimpfwort: function () {
        return this.selectRandomFromArray(this.shimpfwoerter);
    },

    /** This variable holds the currently selected task */
    selectedTask: null,

    /** Select tasks at random */
    selectTask: function() {
        // return this.selectRandomFromArray(this.aufgaben);
        return this.aufgaben[0];
    },

    taskTimeout: null,
    taskInterval: null,

    /** Stop the background jobs */
    clearJobs: function() {
        if(this.taskTimeout) {
            clearTimeout(this.taskTimeout);
        }
        if(this.taskInterval) {
            clearInterval(this.taskInterval);
        }
    },

    /** Select a task and setup the ui */
    setupTask: function(task) {
        this.selectedTask = task;
        $('#anweisung').removeClass('turkisgelb');
        $('#anweisung').removeClass('blaugelb');
        $('#anweisung').removeClass('orangepink');
        $('#anweisung').removeClass('blaupink');
        $('#anweisung').removeClass('pinkorange');
        $('#anweisung').addClass(this.selectedTask.style);
        $('#befehl').html(this.selectedTask.befehl);
        $('#instruktion').html(this.selectedTask.details);

        this.taskTimeout = setTimeout(function() {
            tyf.taskFailed();
        }, 15000);

        this.showSlide('anweisung');
        this.resetOrientationData();
        this.taskInterval = setInterval(function() {
            tyf.executeTask();
        }, 200);
    },

    /** Select a random task and init the UI with it */
    setupRandomTask: function() {
        var t = tyf.selectTask();
        tyf.setupTask(t);
    },

    /** Depending on the task key a certain helper function is called */
    executeTask: function() {
        switch(this.selectedTask.taskKey) {
            case 'aliens': this.executeAlienTask();
        }
    },

    /** Check if the timeseries has a tilting pattern */
    executeAlienTask: function() {
        var found90DegreeGamma;
        var found0DegreeGamma;

        for(var i=0;i<this.orientationData.length;i++) {
            var orientation = this.orientationData[i];
            var gammaAbs = Math.abs(orientation.gamma);
            if(gammaAbs > 70) {
                found90DegreeGamma = orientation.timestamp;
            }
            if(found90DegreeGamma && orientation.timestamp > found90DegreeGamma && orientation.gamma < 20) {
                found0DegreeGamma = orientation.timestamp;
            }
        }

        if(found0DegreeGamma && found90DegreeGamma) {
            this.taskSuccess();
        }
    },

    lastTaskFailed: false,

    /** Switch to the outcome slide and mark it as error */
    taskFailed: function() {
        this.lastTaskFailed = true;
        this.clearJobs();
        $('#outcome').html(this.errorOutcome.outcome);
        $('#outcomesub').html(this.errorOutcome.sub);
        $('#outcomeinst').html(this.errorOutcome.inst);

        $('#ergebnis').removeClass('turkisgelb');
        $('#ergebnis').removeClass('blaugelb');
        $('#ergebnis').removeClass('orangepink');
        $('#ergebnis').removeClass('blaupink');
        $('#ergebnis').removeClass('pinkorange');
        $('#ergebnis').addClass('errorOutcome');

        this.showSlide('ergebnis');
    },

    /** Task was executed correctly */
    taskSuccess: function() {
        this.lastTaskFailed = false;
        this.clearJobs();

        $('#ergebnis').removeClass('turkisgelb');
        $('#ergebnis').removeClass('blaugelb');
        $('#ergebnis').removeClass('orangepink');
        $('#ergebnis').removeClass('blaupink');
        $('#ergebnis').removeClass('pinkorange');
        $('#ergebnis').removeClass('errorOutcome');
        $('#ergebnis').addClass(this.selectedTask.style);

        $('#outcome').html(this.selectedTask.successTitle);
        $('#outcomesub').html(this.selectedTask.successSubTitle);
        $('#outcomeinst').html(this.selectedTask.successTeaser);
        this.showSlide('ergebnis');
    },

    /** Start tracking of device orientation events */
    trackDeviceOrientation: function() {
        if(window.DeviceOrientationEvent) {
            window.addEventListener('deviceorientation', tyf.handleDeviceOrientation, false);
        }else{
            $('#accelStatus').html('Der Bewegunggsensor in deinem Gerät funktioniert leider nicht!');
            $('#accelStatus').show();
        }
    },

    lastOrientationUpdate: null,

    /** Simple ring buffer for orientation data */
    orientationData: [],
    orientationDataInsertPosition: 0,

    /** Handle device orientation event */
    handleDeviceOrientation: function(evt) {
        var now = Date.now();
        if(!tyf.lastOrientationUpdate || now - tyf.lastOrientationUpdate > 200) {
            tyf.lastOrientationUpdate = now;
            $('#orientG').html(evt.gamma.toFixed(3));
            $('#orientB').html(evt.beta.toFixed(3));
            $('#orientA').html(evt.alpha.toFixed(3));
            tyf.orientationData[tyf.orientationDataInsertPosition] = {
                timestamp: now,
                gamma: evt.gamma, beta: evt.beta, alpha: evt.alpha
            };
            tyf.orientationDataInsertPosition = (tyf.orientationDataInsertPosition + 1) % 100;
        }
    },

    /** Clear the orientation data array */
    resetOrientationData: function() {
        tyf.orientationDataInsertPosition = 0;
        tyf.orientationData = [];
    },

    /** If we are on the ergebnis then we need to decide how to handle the click */
    handleErgebnisClick: function() {
        if(this.lastTaskFailed) {
            this.setupRandomTask();
        }else{
            this.showSlide('startscreen');
        }
    },

    /** Show a slide and hide all others */
    showSlide: function (slideId) {
        if (!slideId.startsWith('#')) {
            slideId = '#' + slideId;
        }
        $('.slide').addClass('hidden');
        $(slideId).removeClass('hidden');
    },

    /** Setup the callback handlers for all buttons and slides */
    setupHandlers: function () {
        $('#ichhabeangst').click(function() {
            $('#beschimpfung').html(tyf.selectSchimpfwort());
            tyf.showSlide('schimpfwort');
            setTimeout(function() {
                tyf.showSlide('startscreen');
            }, 3000);
        });
        $('#ichhabekeineangst').click(function () {
            tyf.setupRandomTask();
        });
        $('#ergebnis').click(function () {
            tyf.handleErgebnisClick();
        });
    },

    /** Performs setup of the app and switches to the startscreen afterwards */
	init: function () {
        this.setupHandlers();
        this.trackDeviceOrientation();
        this.showSlide('startscreen');
	}

};

$(document).ready(function() {
	tyf.init();
});
<|endoftext|>


<commit_before>var merge = require('lodash.merge');
var webpack = require('webpack');
var path = require('path');
var url = require('url');
var autoprefixer = require('autoprefixer');
var pkg = require('../package.json');
var BundleTracker = require('webpack-bundle-tracker');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = function (options) {
  var defaultOptions = {
    banner: false,
    debug: false,
    extractCss: false,
    failOnError: false,
    hash: false,
    host: '0.0.0.0',
    hot: false,
    https: false,
    optimize: false,
    outputDir: path.resolve(__dirname, '../jsapp/compiled/'),
    outputHash: true,
    port: 3000,
    publicPath: '/static/compiled/',
    saveStats: false,
  };

  options = merge(defaultOptions, options || {});

  var entry = {
    app: options.entry || path.join(__dirname, '../jsapp/js/main.es6'),
  };

  var scssIncludePaths = ['',
    '~',
    path.join(__dirname, '../jsapp/scss')
  ];

  var autoprefixerOptions = {

    browsers: [
      'ie >= 10',
      'ie_mob >= 10',
      'ff >= 30',
      'chrome >= 34',
      'safari >= 7',
      'opera >= 23',
      'ios >= 7',
      'android >= 4.4',
      'bb >= 10'
    ]
  };

  var banner =
    'Name: ' + pkg.name + '\n' +
    'Version: ' + pkg.version + '\n' +
    'Description: ' + pkg.description;

  var scssLoader = [
    'style-loader',
    [
      'css-loader',
      'postcss-loader',
      'sass-loader?outputStyle=expanded' + scssIncludePaths.join('&includePaths[]='),
    ].join('!')
  ]

  var loaders = [
    {
      test: /\.(js|jsx|es6)$/,
      exclude: /(node_modules|bower_components)/,
      loader: 'react-hot-loader!babel-loader'
    },
    { // for third-party minified scripts, don't process require()
      test: /\.min\.js$/,
      include: /(node_modules|bower_components)/,
      loader: 'script'
    },
    {
      test: /\.json$/,
      loader: 'json-loader'
    },
    {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
    },
    {
      test: /\.scss$/,
      loader: options.extractCss ?
        ExtractTextPlugin.extract(
          scssLoader[0], scssLoader[1]
        ) : scssLoader.join('!')
    },
    {
      test: /\.sass$/,
      loader: 'style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax=sass'
    },
    {
      test: /\.less$/,
      loader: 'style-loader!css-loader!postcss-loader!less-loader'
    },
    {
      test: /\.coffee$/,
      loader: "coffee-loader",
    },
    { test: /\.(coffee\.md|litcoffee)$/,
      loader: "coffee-loader?literate"
    }
  ];

  if (options.hash) {
    loaders.push({
      test: /\.(png|jpg|gif)$/,
      loader: 'file-loader?name=[hash].[ext]'
    });
    loaders.push({
      test: /\.(ttf|eot|svg|woff(2)?)(\S+)?$/,
      loader: 'file-loader?name=[hash].[ext]'
    });
  } else {
    loaders.push({
      test: /\.(png|jpg|gif)$/,
      loader: 'file-loader?name=[name].[ext]'
    });
    loaders.push({
      test: /\.(ttf|eot|svg|woff(2)?)(\S+)?$/,
      loader: 'file-loader?name=[name].[ext]'
    });
  }

  var plugins = [
    new webpack.NoErrorsPlugin(),
  ];

  if (options.extractCss) {
    plugins.push(new ExtractTextPlugin('[name].css'));
  }

  if (options.hot) {
    plugins.push(new webpack.HotModuleReplacementPlugin());
  }

  if (!options.optimize) {
    plugins.push(new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      }
    }));
  } else {
    plugins.push(new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      output: {
        comments: false
      }
    }));
    plugins.push(new webpack.optimize.DedupePlugin());
    plugins.push(new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }));
    plugins.push(new webpack.NoErrorsPlugin());
  }

  if (options.saveStats) {
    plugins.push(
        new BundleTracker({
          path: path.join(__dirname, '..'),
          filename: './webpack-stats.json',
        })
      );
  }

  if (options.banner) {
    plugins.push(new webpack.BannerPlugin(banner));
  }

  var config = {
    entry: Object.keys(entry).reduce(function (result, key) {
      result[key] = options.hot ? [
        'webpack-dev-server/client?http://localhost:3000/',
        'webpack/hot/only-dev-server',
        entry[key]
      ] : entry[key];
      return result;
    }, {}),
    output: {
      path: options.outputDir,
      filename: options.outputHash ? "[name]-[hash].js" : "[name].js",
      publicPath: options.publicPath,
    },
    resolve: {
      extensions: ['', '.jsx', '.js', '.es6', '.coffee'],
      alias: {
        app: path.join(__dirname, '../app'),
        utils: path.join(__dirname, '../jsapp/js/utils'),
        test: path.join(__dirname, '../test'),
      }
    },
    module: {
      preLoaders: [
        {
          test: /\.(js|jsx|es6)$/,
          exclude: /(node_modules|bower_components)/,
          loader: 'eslint-loader'
        }
      ],
      loaders: loaders
    },
    plugins: plugins,
    eslint: {
      configFile: path.join(__dirname, '../.eslintrc'),
      failOnError: options.failOnError,
      emitError: options.failOnError
    },
    postcss: function () {
      return [autoprefixer(autoprefixerOptions)];
    },
    node: {
      fs: 'empty',
      net: 'mock',
      dns: 'mock'
    },
    externals: [
      {
        './cptable': 'var cptable'
      }
    ],
    bail: true,
    debug: options.debug
  };

  if (options.devTool) {
    config.devtool = options.devTool;
  }

  return config;
};
<commit_msg>changing default publicPath to reflect environment variable on staging and production<commit_after>var merge = require('lodash.merge');
var webpack = require('webpack');
var path = require('path');
var url = require('url');
var autoprefixer = require('autoprefixer');
var pkg = require('../package.json');
var BundleTracker = require('webpack-bundle-tracker');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = function (options) {
  var defaultOptions = {
    banner: false,
    debug: false,
    extractCss: false,
    failOnError: false,
    hash: false,
    host: '0.0.0.0',
    hot: false,
    https: false,
    optimize: false,
    outputDir: path.resolve(__dirname, '../jsapp/compiled/'),
    outputHash: true,
    port: 3000,
    // on prod + staging, process.env.KPI_PREFIX is '/forms'
    publicPath: (process.env.KPI_PREFIX || '') + '/static/compiled/',
    saveStats: false,
  };

  options = merge(defaultOptions, options || {});

  var entry = {
    app: options.entry || path.join(__dirname, '../jsapp/js/main.es6'),
  };

  var scssIncludePaths = ['',
    '~',
    path.join(__dirname, '../jsapp/scss')
  ];

  var autoprefixerOptions = {

    browsers: [
      'ie >= 10',
      'ie_mob >= 10',
      'ff >= 30',
      'chrome >= 34',
      'safari >= 7',
      'opera >= 23',
      'ios >= 7',
      'android >= 4.4',
      'bb >= 10'
    ]
  };

  var banner =
    'Name: ' + pkg.name + '\n' +
    'Version: ' + pkg.version + '\n' +
    'Description: ' + pkg.description;

  var scssLoader = [
    'style-loader',
    [
      'css-loader',
      'postcss-loader',
      'sass-loader?outputStyle=expanded' + scssIncludePaths.join('&includePaths[]='),
    ].join('!')
  ]

  var loaders = [
    {
      test: /\.(js|jsx|es6)$/,
      exclude: /(node_modules|bower_components)/,
      loader: 'react-hot-loader!babel-loader'
    },
    { // for third-party minified scripts, don't process require()
      test: /\.min\.js$/,
      include: /(node_modules|bower_components)/,
      loader: 'script'
    },
    {
      test: /\.json$/,
      loader: 'json-loader'
    },
    {
      test: /\.css$/,
      loader: 'style-loader!css-loader'
    },
    {
      test: /\.scss$/,
      loader: options.extractCss ?
        ExtractTextPlugin.extract(
          scssLoader[0], scssLoader[1]
        ) : scssLoader.join('!')
    },
    {
      test: /\.sass$/,
      loader: 'style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax=sass'
    },
    {
      test: /\.less$/,
      loader: 'style-loader!css-loader!postcss-loader!less-loader'
    },
    {
      test: /\.coffee$/,
      loader: "coffee-loader",
    },
    { test: /\.(coffee\.md|litcoffee)$/,
      loader: "coffee-loader?literate"
    }
  ];

  if (options.hash) {
    loaders.push({
      test: /\.(png|jpg|gif)$/,
      loader: 'file-loader?name=[hash].[ext]'
    });
    loaders.push({
      test: /\.(ttf|eot|svg|woff(2)?)(\S+)?$/,
      loader: 'file-loader?name=[hash].[ext]'
    });
  } else {
    loaders.push({
      test: /\.(png|jpg|gif)$/,
      loader: 'file-loader?name=[name].[ext]'
    });
    loaders.push({
      test: /\.(ttf|eot|svg|woff(2)?)(\S+)?$/,
      loader: 'file-loader?name=[name].[ext]'
    });
  }

  var plugins = [
    new webpack.NoErrorsPlugin(),
  ];

  if (options.extractCss) {
    plugins.push(new ExtractTextPlugin('[name].css'));
  }

  if (options.hot) {
    plugins.push(new webpack.HotModuleReplacementPlugin());
  }

  if (!options.optimize) {
    plugins.push(new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"development"'
      }
    }));
  } else {
    plugins.push(new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      },
      output: {
        comments: false
      }
    }));
    plugins.push(new webpack.optimize.DedupePlugin());
    plugins.push(new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    }));
    plugins.push(new webpack.NoErrorsPlugin());
  }

  if (options.saveStats) {
    plugins.push(
        new BundleTracker({
          path: path.join(__dirname, '..'),
          filename: './webpack-stats.json',
        })
      );
  }

  if (options.banner) {
    plugins.push(new webpack.BannerPlugin(banner));
  }

  var config = {
    entry: Object.keys(entry).reduce(function (result, key) {
      result[key] = options.hot ? [
        'webpack-dev-server/client?http://localhost:3000/',
        'webpack/hot/only-dev-server',
        entry[key]
      ] : entry[key];
      return result;
    }, {}),
    output: {
      path: options.outputDir,
      filename: options.outputHash ? "[name]-[hash].js" : "[name].js",
      publicPath: options.publicPath,
    },
    resolve: {
      extensions: ['', '.jsx', '.js', '.es6', '.coffee'],
      alias: {
        app: path.join(__dirname, '../app'),
        utils: path.join(__dirname, '../jsapp/js/utils'),
        test: path.join(__dirname, '../test'),
      }
    },
    module: {
      preLoaders: [
        {
          test: /\.(js|jsx|es6)$/,
          exclude: /(node_modules|bower_components)/,
          loader: 'eslint-loader'
        }
      ],
      loaders: loaders
    },
    plugins: plugins,
    eslint: {
      configFile: path.join(__dirname, '../.eslintrc'),
      failOnError: options.failOnError,
      emitError: options.failOnError
    },
    postcss: function () {
      return [autoprefixer(autoprefixerOptions)];
    },
    node: {
      fs: 'empty',
      net: 'mock',
      dns: 'mock'
    },
    externals: [
      {
        './cptable': 'var cptable'
      }
    ],
    bail: true,
    debug: options.debug
  };

  if (options.devTool) {
    config.devtool = options.devTool;
  }

  return config;
};
<|endoftext|>


<commit_before>'use strict';

const Sequelize = require('sequelize');
//const REMOTE_URL = require('../database.js');
const LOCAL_URL = 'postgres://localhost:5432/softballers';

const sequelize = new Sequelize(LOCAL_URL, { logging: false });

//check connection
sequelize
  .authenticate()
  .then( function(err) {
    console.log('Connection Successful')
  })
  .catch( function(err) {
    console.log('Unable to connect::::', err)
  });

//Model for Admin
const Admin = sequelize.define('admins', {
  username: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: { notEmpty: true },
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: { notEmpty: true },
  }
})
//Model for leagues
const League = sequelize.define('leagues', {
  name: {
    type: Sequelize.STRING
  },
  leagueid: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  }
})

//Model for teams
const Teams = sequelize.define('teams', {
  teamname: {
    type: Sequelize.STRING
  },
  wins: {
    type: Sequelize.INTEGER,
  },
  losses: {
    type: Sequelize.INTEGER,
  },
  league: {
    type: Sequelize.STRING
  }
});

//Model for players
const Player = sequelize.define('players', {
  firstname: {
    type: Sequelize.STRING,
  },
  lastname: {
    type: Sequelize.STRING,
  },
  teamname: {
    type: Sequelize.STRING,
  },
  battingavg: {
    type: Sequelize.INTEGER,
  },
  hits: {
    type: Sequelize.INTEGER,
  },
  atbats: {
    type: Sequelize.INTEGER,
  },
  homeruns: {
    type: Sequelize.INTEGER,
  }

});

//Model for schedule
const Schedule = sequelize.define('schedule', {
  hometeam: {
    type: Sequelize.STRING,
  },
  awayteam: {
    type: Sequelize.STRING,
  },
  week: {
    type: Sequelize.INTEGER,
  },
  location: {
    type: Sequelize.STRING,
  },
  date: {
    type: Sequelize.DATE,
  },
  time: {
    type: Sequelize.STRING,
  },
  league: {
    type: Sequelize.STRING,
  }
});

//Model for stats

sequelize.sync()
  .catch( (error) => {
    console.log(error)
  })

module.exports = {sequelize, Admin, League, Teams, Player, Schedule};
<commit_msg>Rename Teams model to Team<commit_after>'use strict';

const Sequelize = require('sequelize');
//const REMOTE_URL = require('../database.js');
const LOCAL_URL = 'postgres://localhost:5432/softballers';

const sequelize = new Sequelize(LOCAL_URL, { logging: false });

//check connection
sequelize
  .authenticate()
  .then( function(err) {
    console.log('Connection Successful')
  })
  .catch( function(err) {
    console.log('Unable to connect::::', err)
  });

//Model for Admin
const Admin = sequelize.define('admins', {
  username: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: { notEmpty: true },
  },
  password: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: { notEmpty: true },
  }
})
//Model for leagues
const League = sequelize.define('leagues', {
  name: {
    type: Sequelize.STRING
  },
  leagueid: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  }
})

//Model for teams
const Team  = sequelize.define('teams', {
  teamname: {
    type: Sequelize.STRING
  },
  wins: {
    type: Sequelize.INTEGER,
  },
  losses: {
    type: Sequelize.INTEGER,
  },
  league: {
    type: Sequelize.STRING
  }
});

//Model for players
const Player = sequelize.define('players', {
  firstname: {
    type: Sequelize.STRING,
  },
  lastname: {
    type: Sequelize.STRING,
  },
  teamname: {
    type: Sequelize.STRING,
  },
  battingavg: {
    type: Sequelize.INTEGER,
  },
  hits: {
    type: Sequelize.INTEGER,
  },
  atbats: {
    type: Sequelize.INTEGER,
  },
  homeruns: {
    type: Sequelize.INTEGER,
  }

});

//Model for schedule
const Schedule = sequelize.define('schedule', {
  hometeam: {
    type: Sequelize.STRING,
  },
  awayteam: {
    type: Sequelize.STRING,
  },
  week: {
    type: Sequelize.INTEGER,
  },
  location: {
    type: Sequelize.STRING,
  },
  date: {
    type: Sequelize.DATE,
  },
  time: {
    type: Sequelize.STRING,
  },
  league: {
    type: Sequelize.STRING,
  }
});

//Model for stats

sequelize.sync()
  .catch( (error) => {
    console.log(error)
  })

module.exports = {sequelize, Admin, League, Team , Player, Schedule};
<|endoftext|>


<commit_before>//-------------------------------------------------------------------
// Marbles Chaincode - Deploy Chaincode
//-------------------------------------------------------------------
var path = require('path');

module.exports = function (chain, chaincode_id, logger) {
	var deploy_cc = {};

	//-------------------------------------------------------------------
	// Check if Chaincode Is Already Deployed
	//-------------------------------------------------------------------
	deploy_cc.check_if_already_deployed = function (webUser, peerUrls, cb) {
		// send query
		var request = {
			targets: peerUrls,
			chaincodeId : chaincode_id,
			fcn: 'read',
			args: ['_ownerindex']
		};
		webUser.queryByChaincode(request)
		.then(
			function(response_payloads) {
				if(response_payloads.length <= 0){									//error
					console.log('Query response is empty: ');
					if(cb) return cb({error: 'query response is empty'});
				}
				else{																//success
					for(var i in response_payloads) {								//print each peer's payload
						console.log('Peer' + i, 'payload says:', response_payloads[i].toString('utf8'));
					}
					console.log('---------------------------------------------------------------------------');
					if(cb) return cb(null);
				}
			},
			function(err) {															//error
				console.log('Failed to send query due to error: ' + err.stack ? err.stack : err);
			}
		).catch(
			function(err) {															//error
				console.log('Failed, in catch block?' + err.stack ? err.stack : err);
			}
		);
	};

	//-------------------------------------------------------------------
	// Deploy Chaincode
	//-------------------------------------------------------------------
	deploy_cc.deploy_chaincode = function (webUser, peerUrls, cb) {
		// send proposal to endorser
		var request = {
			targets: peerUrls,
			chaincodePath: screwy_path('./chaincode'),								//path from marbles root to marbles chaincode folder
			chaincodeId: chaincode_id,
			fcn: 'init',
			args: ['99'],
			'dockerfile-contents' :
			'from hyperledger/fabric-ccenv\n' +
			'COPY . $GOPATH/src/build-chaincode/\n' +
			'WORKDIR $GOPATH\n\n' +
			'RUN go install build-chaincode && mv $GOPATH/bin/build-chaincode $GOPATH/bin/%s'
		};

		webUser.sendDeploymentProposal(request)
		.then(
			function(results) {
				var proposalResponses = results[0];
				var proposal = results[1];
				if (proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200) {
					console.log('Successfully sent Proposal and received ProposalResponse: ');
					console.log('\tStatus -', proposalResponses[0].response.status, 'message -', proposalResponses[0].response.message);
					console.log('metadata -', proposalResponses[0].response.payload, 'endorsement signature:', proposalResponses[0].endorsement.signature);
					return webUser.sendTransaction(proposalResponses, proposal);
				}
				else{
					console.log('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
				}
			}
		).then(
			function(response) {
				if (response.Status === 'SUCCESS') {
					console.log('Successfully ordered deployment endorsement.');
					setTimeout(function(){
						console.log('\n\n---------------------------------------------------------------------------');
						console.log('Chaincode deployed successfully\n\n');
						if(cb) return cb(null);
						else return;
					}, 25000);
				}
				else{
					console.log('Failed to order the deployment endorsement.');
				}
			}
		).catch(
			function(err){
				console.log('Failed to deploy, in catch block');
				if(cb) return cb(err);
			}
		);
	};

	//get the path from GOPATH to marble's chaincode folder (b/c hfc expects the path to be this way)
	//hfc builds the path with: projDir = goPath + '/src/' + chaincodePath; - therefore chaincodePath must reference from GOPATH/src/
	function screwy_path(chaincode_folder){
		var pos = __dirname.indexOf(path.join(process.env.GOPATH + '/src/'));
		if(pos === -1){
			var msg = '[Deploy Error] Marbles is not inside your system GOPATH, please fix';
			console.log('\n\n' + msg + '\n\n');
			throw msg;
		}
		else{
			var removedGo = __dirname.substring(process.env.GOPATH.length + 5);		//remove GOPATH/src part from __dirname
			console.log('[debug] removedGo from marbles path', removedGo);

			var temp = __dirname.replace('/', '\\');
			var parsed = temp.split('\\');
			var root_of_marbles = parsed[parsed.length-3];							//find name of marbles root dir
			console.log('[debug] root_of_marbles path', root_of_marbles);

			var pos3 = removedGo.indexOf(root_of_marbles);
			var hfc_path = removedGo.substring(0, pos3 + root_of_marbles.length);	//get path from GOPATH to marbles root dir

			var ret = path.join(hfc_path, chaincode_folder);						//path to chaincode dir
			console.log('[debug] hfc compatible path to chaincode dir', ret);

			return ret;
			//var debug = process.env.GOPATH + '/src/' + ret; 						//<- this is what hfc will build..
			//console.log('debug', debug);
		}
	}

	return deploy_cc;
};

<commit_msg>fix linux path delimiter spliting<commit_after>//-------------------------------------------------------------------
// Marbles Chaincode - Deploy Chaincode
//-------------------------------------------------------------------
var path = require('path');

module.exports = function (chain, chaincode_id, logger) {
	var deploy_cc = {};

	//-------------------------------------------------------------------
	// Check if Chaincode Is Already Deployed
	//-------------------------------------------------------------------
	deploy_cc.check_if_already_deployed = function (webUser, peerUrls, cb) {
		// send query
		var request = {
			targets: peerUrls,
			chaincodeId : chaincode_id,
			fcn: 'read',
			args: ['_ownerindex']
		};
		webUser.queryByChaincode(request)
		.then(
			function(response_payloads) {
				if(response_payloads.length <= 0){									//error
					console.log('Query response is empty: ');
					if(cb) return cb({error: 'query response is empty'});
				}
				else{																//success
					for(var i in response_payloads) {								//print each peer's payload
						console.log('Peer' + i, 'payload says:', response_payloads[i].toString('utf8'));
					}
					console.log('---------------------------------------------------------------------------');
					if(cb) return cb(null);
				}
			},
			function(err) {															//error
				console.log('Failed to send query due to error: ' + err.stack ? err.stack : err);
			}
		).catch(
			function(err) {															//error
				console.log('Failed, in catch block?' + err.stack ? err.stack : err);
			}
		);
	};

	//-------------------------------------------------------------------
	// Deploy Chaincode
	//-------------------------------------------------------------------
	deploy_cc.deploy_chaincode = function (webUser, peerUrls, cb) {
		// send proposal to endorser
		var request = {
			targets: peerUrls,
			chaincodePath: screwy_path('./chaincode'),								//path from marbles root to marbles chaincode folder
			chaincodeId: chaincode_id,
			fcn: 'init',
			args: ['99'],
			'dockerfile-contents' :
			'from hyperledger/fabric-ccenv\n' +
			'COPY . $GOPATH/src/build-chaincode/\n' +
			'WORKDIR $GOPATH\n\n' +
			'RUN go install build-chaincode && mv $GOPATH/bin/build-chaincode $GOPATH/bin/%s'
		};

		webUser.sendDeploymentProposal(request)
		.then(
			function(results) {
				var proposalResponses = results[0];
				var proposal = results[1];
				if (proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200) {
					console.log('Successfully sent Proposal and received ProposalResponse: ');
					console.log('\tStatus -', proposalResponses[0].response.status, 'message -', proposalResponses[0].response.message);
					console.log('metadata -', proposalResponses[0].response.payload, 'endorsement signature:', proposalResponses[0].endorsement.signature);
					return webUser.sendTransaction(proposalResponses, proposal);
				}
				else{
					console.log('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
				}
			}
		).then(
			function(response) {
				if (response.Status === 'SUCCESS') {
					console.log('Successfully ordered deployment endorsement.');
					setTimeout(function(){
						console.log('\n\n---------------------------------------------------------------------------');
						console.log('Chaincode deployed successfully\n\n');
						if(cb) return cb(null);
						else return;
					}, 25000);
				}
				else{
					console.log('Failed to order the deployment endorsement.');
				}
			}
		).catch(
			function(err){
				console.log('Failed to deploy, in catch block');
				if(cb) return cb(err);
			}
		);
	};

	//get the path from GOPATH to marble's chaincode folder (b/c hfc expects the path to be this way)
	//hfc builds the path with: projDir = goPath + '/src/' + chaincodePath; - therefore chaincodePath must reference from GOPATH/src/
	function screwy_path(chaincode_folder){
		var pos = __dirname.indexOf(path.join(process.env.GOPATH + '/src/'));
		if(pos === -1){
			var msg = '[Deploy Error] Marbles is not inside your system GOPATH, please fix';
			console.log('\n\n' + msg + '\n\n');
			throw msg;
		}
		else{
			var removedGo = __dirname.substring(process.env.GOPATH.length + 5);		//remove GOPATH/src part from __dirname
			console.log('[debug] removedGo from marbles path', removedGo);

			var parsed = __dirname.split(path.delimiter);
			var root_of_marbles = parsed[parsed.length-3];							//find name of marbles root dir
			console.log('[debug] root_of_marbles path', root_of_marbles);

			var pos3 = removedGo.indexOf(root_of_marbles);
			var hfc_path = removedGo.substring(0, pos3 + root_of_marbles.length);	//get path from GOPATH to marbles root dir

			var ret = path.join(hfc_path, chaincode_folder);						//path to chaincode dir
			console.log('[debug] hfc compatible path to chaincode dir', ret);

			return ret;
			//var debug = process.env.GOPATH + '/src/' + ret; 						//<- this is what hfc will build..
			//console.log('debug', debug);
		}
	}

	return deploy_cc;
};

<|endoftext|>


<commit_before>/* eslint-env jest */

import React from 'react'
import {
  shallow
} from 'enzyme'
import toJson from 'enzyme-to-json'
import Typography from '@material-ui/core/Typography'
import {
  getUrlParameters
} from 'js/utils/utils'

jest.mock('js/utils/utils')

describe('SignInIframeMessage tests', () => {
  it('renders without error', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    shallow(
      <SignInIframeMessage />
    )
  })

  it('redirects the page when clicking the sign-in button', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default

    // Mock window.open
    window.open = jest.fn()

    const wrapper = shallow(
      <SignInIframeMessage />
    )
    const signInButton = wrapper.find('[data-test-id="sign-in-iframe-message-button"]')

    expect(window.open).not.toHaveBeenCalled()
    signInButton.simulate('click')
    expect(window.open).toHaveBeenCalled()
  })

  it('has the expected copy', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    const wrapper = shallow(
      <SignInIframeMessage />
    )
    expect(
      wrapper.find(Typography)
        .first().children().text())
      .toBe(`Let's get started!`)
    expect(
      wrapper.find(Typography)
        .at(1).children().text())
      .toBe(
        `Sign in to customize your new tab page and raise money for your favorite causes.`)
  })

  it('shows the explanation copy when an anonymous user is now required to sign in', () => {
    getUrlParameters.mockReturnValueOnce({
      mandatory: 'true'
    })
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    const wrapper = shallow(
      <SignInIframeMessage />
    )
    expect(
      wrapper.find(Typography)
        .first().children().text())
      .toBe(`Great job so far!`)
    expect(
      wrapper.find(Typography)
        .at(1).children().text())
      .toMatch(
        `You've already made a positive impact! Let's keep this progress safe:`)
  })
})
<commit_msg>Lint fix<commit_after>/* eslint-env jest */

import React from 'react'
import {
  shallow
} from 'enzyme'
import Typography from '@material-ui/core/Typography'
import {
  getUrlParameters
} from 'js/utils/utils'

jest.mock('js/utils/utils')

describe('SignInIframeMessage tests', () => {
  it('renders without error', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    shallow(
      <SignInIframeMessage />
    )
  })

  it('redirects the page when clicking the sign-in button', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default

    // Mock window.open
    window.open = jest.fn()

    const wrapper = shallow(
      <SignInIframeMessage />
    )
    const signInButton = wrapper.find('[data-test-id="sign-in-iframe-message-button"]')

    expect(window.open).not.toHaveBeenCalled()
    signInButton.simulate('click')
    expect(window.open).toHaveBeenCalled()
  })

  it('has the expected copy', () => {
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    const wrapper = shallow(
      <SignInIframeMessage />
    )
    expect(
      wrapper.find(Typography)
        .first().children().text())
      .toBe(`Let's get started!`)
    expect(
      wrapper.find(Typography)
        .at(1).children().text())
      .toBe(
        `Sign in to customize your new tab page and raise money for your favorite causes.`)
  })

  it('shows the explanation copy when an anonymous user is now required to sign in', () => {
    getUrlParameters.mockReturnValueOnce({
      mandatory: 'true'
    })
    const SignInIframeMessage = require('js/components/Authentication/SignInIframeMessage').default
    const wrapper = shallow(
      <SignInIframeMessage />
    )
    expect(
      wrapper.find(Typography)
        .first().children().text())
      .toBe(`Great job so far!`)
    expect(
      wrapper.find(Typography)
        .at(1).children().text())
      .toMatch(
        `You've already made a positive impact! Let's keep this progress safe:`)
  })
})
<|endoftext|>


<commit_before>import Component from '@ember/component';
import classic from 'ember-classic-decorator';
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
import {action, computed} from '@ember/object';
import {inject as service} from '@ember/service';
import {tagName} from '@ember-decorators/component';
import {task, timeout} from 'ember-concurrency';

@classic
@tagName('')
export default class GhPortalLinks extends Component {
    @service config;
    @service store;
    @service settings;

    isLink = true;
    prices = null;
    copiedPrice = null;
    copiedSignupInterval = null;
    selectedProduct = null;
    products = null;

    @computed('isLink')
    get toggleValue() {
        return this.isLink ? 'Data attributes' : 'Links';
    }

    @computed('isLink')
    get sectionHeaderLabel() {
        return this.isLink ? 'Link' : 'Data attribute';
    }

    @computed('selectedProduct')
    get selectedProductIdPath() {
        const selectedProduct = this.selectedProduct;
        if (selectedProduct) {
            return `/${selectedProduct.name}`;
        }
        return '';
    }

    @computed('products.[]')
    get productOptions() {
        if (this.products) {
            return this.products.map((product) => {
                return {
                    label: product.name,
                    name: product.id
                };
            });
        }
        return [];
    }

    init() {
        super.init(...arguments);
        this.siteUrl = this.config.get('blogUrl');
    }

    @action
    toggleShowLinks() {
        this.toggleProperty('isLink');
    }

    @action
    setSelectedProduct(product) {
        this.set('selectedProduct', product);
    }

    @task(function* () {
        const products = yield this.store.query('product', {filter: 'type:paid', include: 'monthly_price,yearly_price'}) || [];
        this.set('products', products);
        if (products.length > 0) {
            this.set('selectedProduct', {
                name: products.firstObject.id,
                label: products.firstObject.name
            });
        }
    })
        fetchProducts;

    @task(function* (id) {
        this.set('copiedPrice', id);
        let data = '';
        if (this.isLink) {
            data = id ? `#/portal/${id}` : `#/portal/`;
        } else {
            data = id ? `data-portal="${id}"` : `data-portal`;
        }
        copyTextToClipboard(data);
        yield timeout(this.isTesting ? 50 : 3000);
    })
        copyStaticLink;

    @task(function* (interval) {
        this.set('copiedSignupInterval', interval);
        let data = '';
        if (this.isLink) {
            data = `#/portal/signup${this.selectedProductIdPath}/${interval}`;
        } else {
            data = `data-portal="signup${this.selectedProductIdPath}/${interval}"`;
        }
        copyTextToClipboard(data);
        yield timeout(this.isTesting ? 50 : 3000);
    })
        copyProductSignupLink;
}
<commit_msg>Updated portal links copy function<commit_after>import Component from '@ember/component';
import classic from 'ember-classic-decorator';
import copyTextToClipboard from 'ghost-admin/utils/copy-text-to-clipboard';
import {action, computed} from '@ember/object';
import {inject as service} from '@ember/service';
import {tagName} from '@ember-decorators/component';
import {task, timeout} from 'ember-concurrency';

@classic
@tagName('')
export default class GhPortalLinks extends Component {
    @service config;
    @service store;
    @service settings;

    isLink = true;
    prices = null;
    copiedPrice = null;
    copiedSignupInterval = null;
    selectedProduct = null;
    products = null;

    @computed('isLink')
    get toggleValue() {
        return this.isLink ? 'Data attributes' : 'Links';
    }

    @computed('isLink')
    get sectionHeaderLabel() {
        return this.isLink ? 'Link' : 'Data attribute';
    }

    @computed('selectedProduct')
    get selectedProductIdPath() {
        const selectedProduct = this.selectedProduct;
        if (selectedProduct) {
            return `/${selectedProduct.name}`;
        }
        return '';
    }

    @computed('products.[]')
    get productOptions() {
        if (this.products) {
            return this.products.map((product) => {
                return {
                    label: product.name,
                    name: product.id
                };
            });
        }
        return [];
    }

    init() {
        super.init(...arguments);
        this.siteUrl = this.config.get('blogUrl');
    }

    @action
    toggleShowLinks() {
        this.toggleProperty('isLink');
    }

    @action
    setSelectedProduct(product) {
        this.set('selectedProduct', product);
    }

    @task(function* () {
        const products = yield this.store.query('product', {filter: 'type:paid', include: 'monthly_price,yearly_price'}) || [];
        this.set('products', products);
        if (products.length > 0) {
            this.set('selectedProduct', {
                name: products.firstObject.id,
                label: products.firstObject.name
            });
        }
    })
        fetchProducts;

    @task(function* (id) {
        this.set('copiedPrice', id);
        let data = '';
        if (this.isLink) {
            data = id ? `#/portal/${id}` : `#/portal/`;
            data = this.siteUrl + `/` + data;
        } else {
            data = id ? `data-portal="${id}"` : `data-portal`;
        }
        copyTextToClipboard(data);
        yield timeout(this.isTesting ? 50 : 3000);
    })
        copyStaticLink;

    @task(function* (interval) {
        this.set('copiedSignupInterval', interval);
        let data = '';
        if (this.isLink) {
            data = `#/portal/signup${this.selectedProductIdPath}/${interval}`;
            data = this.siteUrl + `/` + data;
        } else {
            data = `data-portal="signup${this.selectedProductIdPath}/${interval}"`;
        }
        copyTextToClipboard(data);
        yield timeout(this.isTesting ? 50 : 3000);
    })
        copyProductSignupLink;
}
<|endoftext|>


<commit_before>namespace('Sy');

/**
 * Default implementation of the service container interface
 *
 * @package Sy
 * @class
 * @implements {Sy.ServiceContainerInterface}
 *
 * @param {string} name
 */

Sy.ServiceContainer = function (name) {

    this.name = '';
    this.services = {};
    this.creators = {};

    this.setName(name);

};

Sy.ServiceContainer.prototype = Object.create(Sy.ServiceContainerInterface.prototype, {

    /**
     * @inheritDoc
     */

    get: {

        value: function (serviceName) {

            if (this.services[serviceName] === undefined && this.creators[serviceName]) {

                this.services[serviceName] = this.creators[serviceName].fn.apply({}, this.creators[serviceName].args);
                delete this.creators[serviceName];

            } else if (this.services[serviceName] === undefined) {

                throw new TypeError('Unknown service');

            }

            return this.services[serviceName];

        }

    },

    /**
     * @inheritDoc
     */

    set: {

        value: function (serviceName, creator, args) {

            var regexp = new RegExp(/^((\w+::)|(\w+))+$/gi);

            if (!regexp.test(serviceName)) {
                throw new SyntaxError('Service name "' + serviceName + '" does not follow pattern convention');
            }

            if (typeof creator != 'function'){
                throw new TypeError('Invalid creator type');
            }

            if (args && !(args instanceof Array)) {
                throw new TypeError('Invalid args type (must be an array)');
            }

            if (this.creators[serviceName] !== undefined || this.services[serviceName] !== undefined) {
                throw new TypeError('Service name already used');
            }

            this.creators[serviceName] = {
                fn: creator,
                args: args
            };

            return this;

        }

    },

    /**
     * @inheritDoc
     */

    getName: {

        value: function () {

            return this.name;

        }

    },

    /**
     * @inheritDoc
     */

    setName: {
        value: function (name) {

            this.name = name;

            return this;

        }
    }

});<commit_msg>changed exception to 'ReferenceError' when trying to get unknown service<commit_after>namespace('Sy');

/**
 * Default implementation of the service container interface
 *
 * @package Sy
 * @class
 * @implements {Sy.ServiceContainerInterface}
 *
 * @param {string} name
 */

Sy.ServiceContainer = function (name) {

    this.name = '';
    this.services = {};
    this.creators = {};

    this.setName(name);

};

Sy.ServiceContainer.prototype = Object.create(Sy.ServiceContainerInterface.prototype, {

    /**
     * @inheritDoc
     */

    get: {

        value: function (serviceName) {

            if (this.services[serviceName] === undefined && this.creators[serviceName]) {

                this.services[serviceName] = this.creators[serviceName].fn.apply({}, this.creators[serviceName].args);
                delete this.creators[serviceName];

            } else if (this.services[serviceName] === undefined) {

                throw new ReferenceError('Unknown service');

            }

            return this.services[serviceName];

        }

    },

    /**
     * @inheritDoc
     */

    set: {

        value: function (serviceName, creator, args) {

            var regexp = new RegExp(/^((\w+::)|(\w+))+$/gi);

            if (!regexp.test(serviceName)) {
                throw new SyntaxError('Service name "' + serviceName + '" does not follow pattern convention');
            }

            if (typeof creator != 'function'){
                throw new TypeError('Invalid creator type');
            }

            if (args && !(args instanceof Array)) {
                throw new TypeError('Invalid args type (must be an array)');
            }

            if (this.creators[serviceName] !== undefined || this.services[serviceName] !== undefined) {
                throw new TypeError('Service name already used');
            }

            this.creators[serviceName] = {
                fn: creator,
                args: args
            };

            return this;

        }

    },

    /**
     * @inheritDoc
     */

    getName: {

        value: function () {

            return this.name;

        }

    },

    /**
     * @inheritDoc
     */

    setName: {
        value: function (name) {

            this.name = name;

            return this;

        }
    }

});<|endoftext|>


<commit_before>console.log('download.js loaded')

downloadData=function(div){
    console.log('downloading ...')
    downloadData.getParms()
    // extract limit from url if provided
    if(downloadData.parms.url.match(/limit=\d+/)){
        downloadData.parms.limit=parseInt(downloadData.parms.url.match(/limit=(\d+)/)[1])
    }
    //div.innerHTML='

Maximum number of features to download: <input id="downloadDataLimitInput" size=6> <button class="btn btn-primary" id="downloadButton">Download</button>'
    //downloadDataLimitInput.value=100000
    //downloadData.parms.url=downloadData.parms.url.replace(/limit=\d+&/,'').replace(/"\$gte"\:[0123456789\.]+/,'"$gte":0')
    //downloadData.parms.url=downloadData.parms.url.replace('"randval":{"$gte":0},','')
    // 'properties.scalar_features.nv' :

    downloadData.parms.url=downloadData.parms.url.replace(/limit=\d+&/,'').replace(/"\$gte"\:[0123456789\.]+/,'"$gte":0')
    div.innerHTML='

Maximum number of features to download: <input style="color:blue" id="downloadDataLimitInput" size=6> <button class="btn btn-primary" id="downloadButton" disabled>Start download</button>
<button id="saveFileJsonBt" class="btn btn-success" disabled>Save (partial) File as JSON</button> <button id="saveFileCsvBt" class="btn btn-success" disabled>Save (partial) File as CSV</button> (Chrome browser)'
    downloadDataLimitInput.value=100000
    downloadData.msg=function(m,c){
        downloadDataLimitMsg.style.color=c||'blue'
        downloadDataLimitMsg.innerHTML=m
    }

    var findQuery = function(pre){ //assemble find string where "randval":{"$gte":0} is
        pre=pre||''
        return downloadData.parms.url.replace('"randval":{"$gte":0},',pre+'"$and":[{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$gte" : '+downloadData.parms.xmin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$lte" : '+downloadData.parms.xmax+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$gte" : '+downloadData.parms.ymin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$lte" : '+downloadData.parms.ymax+'}}}}}}],')
    }

    downloadData.msg('estimating size of dataset ...','blue')
    //$.getJSON(downloadData.parms.url.replace('"$gte":0','"$gte":0.999')+'&limit=1000') // sample 1/1000th of the features
    $.getJSON(findQuery('"randval":{"$gte":0.999},')+'&limit=1000')
     .then(function(x){
         var n=x.length
         if(n>100){
             downloadData.msg('About '+n+',000 expected. That will take a while, for something faster maybe go back to the plot and select a smaller area','red')
         }else if(n>10){
             downloadData.msg('About '+n+',000 expected. It will take a few seconds to retrieve them','orange')
         }else{
             downloadData.msg('fewer than 10,000 features expected, it woudn\'t take long to retrieve them all','green')
         }
         downloadData.parms.pn=n*1000 // predicted n
         downloadData.parms.x=x
         downloadButton.disabled=false
     })
     //downloadData.parms.urlFind=downloadData.parms.url.replace('"randval":{"$gte":0},','"$and":[{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$gte" : '+downloadData.parms.xmin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$lte" : '+downloadData.parms.xmax+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$gte" : '+downloadData.parms.ymin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$lte" : '+downloadData.parms.ymax+'}}}}}}],')
     downloadData.parms.urlFind=findQuery()

     downloadButton.onclick=function(){
         downloadButton.disabled=true
         downloadButton.textContent='Downloading ...'
         downloadData.msg('preparing download ...','red')
         // first find out what fields are there to retrieve
         /*
         var getFields=function(){
             var x = downloadData.propertiesArray(downloadData.parms.x)
         }
         getFields()
         */
         downloadData.getData()

     }
     saveFileJsonBt.onclick=function(){

         jmat.saveFile(JSON.stringify(downloadData.dt),'features.json')
     }

     saveFileCsvBt.onclick=function(){
         var ff = Object.getOwnPropertyNames(downloadData.dt[0]).sort()
         var csv=ff.join(',')+'\n' // header
         downloadData.dt.forEach(function(r){
             var x = []
             ff.forEach(function(f){
                 x.push(r[f])
             })
             csv+=x.join(',')+'\n'
         })
         jmat.saveFile(csv.slice(0,-1),'features.csv')

     }

}

downloadData.propertiesArray=function(x){ // convert ns in an awway into an arra of ns
    return x.map(function(xi){
        var y = {}
        xi = xi.properties.scalar_features[0].nv.forEach(function(z){
            y[z.name]=z.value
        })
        return y
    })
}

downloadData.getParms=function(){ // extract parameters from url search
    downloadData.parms=downloadData.parms||{}
    location.search.slice(1).split('&')
     .forEach(function(pp){
         pp = pp.split('=')
         downloadData.parms[pp[0]]=decodeURIComponent(decodeURIComponent(pp[1]))
     })
    //var pp = decodeURIComponent(decodeURIComponent(location.search)).slice(1)
}

// get the data

downloadData.dataTabling=function(){
    saveFileJsonBt.textContent='Save File as JSON'
    saveFileCsvBt.textContent='Save File as CSV'
    var div = document.getElementById('dataTabling')|| document.createElement('div')
    div.id='dataTabling'
    div.innerHTML='
Variables:

<button class="btn btn-success" id="showhideData">tabulate data</button>

'
    downloadDataDiv.appendChild(div)
    downloadData.fieldsChecked=[]
    if(downloadData.dt.length>0){
        downloadData.fields=Object.getOwnPropertyNames(downloadData.dt[0]).sort()
        downloadData.fields.forEach(function(p,i){
            var sp = document.createElement('span')
            var ip = document.createElement('input')
            ip.type='radio'
            ip.value=p
            if(i<3){
                ip.checked=true
                ip.nocheck=false
                downloadData.fieldsChecked.push(p)
            } else {
                ip.checked=false
                ip.nocheck=true
            }
            var h = ' '+p
            sp.innerHTML = h
            sp.appendChild(ip)
            sp.style.color='navy'
            tableVars.appendChild(sp)
            ip.onclick=function(){
                this.nocheck=!this.nocheck
                this.checked=!this.nocheck
                if(this.nocheck){
                    downloadData.fieldsChecked.pop(downloadData.fieldsChecked.indexOf(this.value))
                } else {
                    downloadData.fieldsChecked.push(this.value) // add to list of selected fields
                }
                console.log(downloadData.fieldsChecked)
            }
        })
    }
    showhideData.onclick=function(){
        var div = document.getElementById('tableData')
        div.innerHTML='' // clear if something is there
        div.appendChild(downloadData.docs2html(downloadData.dt,downloadData.fieldsChecked))
    }

    4
}

downloadData.docs2html=function(docs,parms){
    parms = parms || Object.getOwnPropertyNames(docs[0])
    var tb = document.createElement('table')
    tb.cellSpacing='5px'
    var th = document.createElement('thead')
    tb.appendChild(th)
    var trh = document.createElement('tr')
    trh.style.fontSize='10px'
    trh.style.color='navy'
    th.appendChild(trh)
    parms.forEach(function(p){
        var td = document.createElement('td')
        td.textContent=p
        td.style.padding='3px'
        trh.appendChild(td)
    })
    var tbd = document.createElement('tbody')
    tb.appendChild(tbd)

    docs.forEach(function(d){
        var tr = document.createElement('tr')
        tr.style.fontSize='10px'
        tbd.appendChild(tr)
        parms.forEach(function(p){
            var td = document.createElement('td')
            td.style.padding='3px'
            td.textContent=d[p]
            tr.appendChild(td)
            4
        })
    })
    return tb
}

downloadData.getData=function(){
    var n =  1000 // at a time
    if(!downloadData.dt){downloadData.dt=[]}
    //if(!downloadData.parms.n){downloadData.parms.n=0}
    if(!downloadData.parms.lastId){
        var url= downloadData.parms.urlFind+'&limit='+n
    }else{
        //var url=downloadData.parms.urlFind.replace('find={','find={"_id":{"$gt":"'+downloadData.parms.lastId+'"},')+'&limit='+n
        var url= downloadData.parms.urlFind+'&limit='+n+'&offset="'+downloadData.parms.lastId+'"'
    }
    //url = url.replace('http://quip1.uhmc.sunysb.edu','http://129.49.249.191')
    $.getJSON(url)
     .then(function(x){
         try{
             if(!Array.isArray(x)){x=[]}
             //downloadData.parms.n+=x.length
             if(x.length>0){
                 downloadData.parms.lastId=x.slice(-1)[0]._id
                 downloadData.dt=downloadData.dt.concat(downloadData.propertiesArray(x))
                 console.log(Date()+' n = '+downloadData.dt.length+', last _id = '+downloadData.parms.lastId)
             }
             downloadData.msg('features retrieved so far: '+downloadData.dt.length+' out of an estimated total of '+downloadData.parms.pn+' ...','orange')
             if((x.length==n)&(x.length<parseInt(downloadDataLimitInput.value))){
                 setTimeout(function(){
                    //downloadData.parms.urlFind = downloadData.parms.urlFind.replace('http://quip1.uhmc.sunysb.edu','http://129.49.249.191')
                    downloadData.getData()
                 },1000)
             }else{
                 downloadData.dt=downloadData.dt.slice(0,Math.min(downloadData.dt.length,parseInt(downloadDataLimitInput.value)))
                 var N=downloadData.dt.length
                 var M=Object.getOwnPropertyNames(downloadData.dt[0]).length
                 downloadData.msg('Data retrieval ended, '+N+' x '+M+' = '+(N*M)+' values retrieved','green') //, it can be resumed by clicking on Download','green')
                 downloadButton.disabled=false
                 downloadButton.textContent='New Download'
                 downloadButton.style.backgroundColor='orange'
                 downloadButton.style.color='green'
                 downloadButton.onclick=function(){
                     window.open(location.href)
                 }
                 // make data tables available
                 downloadData.dataTabling()
             }
             saveFileJsonBt.disabled=false
             saveFileCsvBt.disabled=false
         }
         catch(err){
             console.log(Date()+' error:',x)
             setTimeout(function(){
                 downloadData.getData()
             },1000)

         }

     })
     .fail(function(err){
         downloadData.msg('Connection Error :-( ','red')
     })

    4
}

// Run
if(document.getElementById('downloadDataDiv')){
    downloadData(downloadDataDiv)
}
window.onload=function(){
    if(document.getElementById('downloadDataDiv')){
        downloadData(downloadDataDiv)
    }
}

/*
example
http://quip1.uhmc.sunysb.edu:3000/?limit=1000&find={%22randval%22:{%22$gte%22:0.17426561033975674},%22provenance.analysis.execution_id%22:%22luad:bg:20160520%22,%22provenance.image.case_id%22:%22TCGA-55-6543-01Z-00-DX1%22}&db=u24_luad

*/<commit_msg>Remove save file as JSON button<commit_after>console.log('download.js loaded')

downloadData=function(div){
    console.log('downloading ...')
    downloadData.getParms()
    // extract limit from url if provided
    if(downloadData.parms.url.match(/limit=\d+/)){
        downloadData.parms.limit=parseInt(downloadData.parms.url.match(/limit=(\d+)/)[1])
    }
    //div.innerHTML='

Maximum number of features to download: <input id="downloadDataLimitInput" size=6> <button class="btn btn-primary" id="downloadButton">Download</button>'
    //downloadDataLimitInput.value=100000
    //downloadData.parms.url=downloadData.parms.url.replace(/limit=\d+&/,'').replace(/"\$gte"\:[0123456789\.]+/,'"$gte":0')
    //downloadData.parms.url=downloadData.parms.url.replace('"randval":{"$gte":0},','')
    // 'properties.scalar_features.nv':

    downloadData.parms.url=downloadData.parms.url.replace(/limit=\d+&/,'').replace(/"\$gte"\:[0123456789\.]+/,'"$gte":0')
    div.innerHTML='

Maximum number of features to download: <input style="color:blue" id="downloadDataLimitInput" size=6> <button class="btn btn-primary" id="downloadButton" disabled>Start download</button>
 <button id="saveFileCsvBt" class="btn btn-success" disabled>Save (partial) File as CSV</button> (Chrome browser)'
    downloadDataLimitInput.value=100000
    downloadData.msg=function(m,c){
        downloadDataLimitMsg.style.color=c||'blue'
        downloadDataLimitMsg.innerHTML=m
    }

    var findQuery = function(pre){ //assemble find string where "randval":{"$gte":0} is
        pre=pre||''
        return downloadData.parms.url.replace('"randval":{"$gte":0},',pre+'"$and":[{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$gte" : '+downloadData.parms.xmin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$lte" : '+downloadData.parms.xmax+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$gte" : '+downloadData.parms.ymin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$lte" : '+downloadData.parms.ymax+'}}}}}}],')
    }

    downloadData.msg('estimating size of dataset ...','blue')
    //$.getJSON(downloadData.parms.url.replace('"$gte":0','"$gte":0.999')+'&limit=1000') // sample 1/1000th of the features
    $.getJSON(findQuery('"randval":{"$gte":0.999},')+'&limit=1000')
     .then(function(x){
         var n=x.length
         if(n>100){
             downloadData.msg('About '+n+',000 expected. That will take a while, for something faster maybe go back to the plot and select a smaller area','red')
         }else if(n>10){
             downloadData.msg('About '+n+',000 expected. It will take a few seconds to retrieve them','orange')
         }else{
             downloadData.msg('fewer than 10,000 features expected, it woudn\'t take long to retrieve them all','green')
         }
         downloadData.parms.pn=n*1000 // predicted n
         downloadData.parms.x=x
         downloadButton.disabled=false
     })
     //downloadData.parms.urlFind=downloadData.parms.url.replace('"randval":{"$gte":0},','"$and":[{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$gte" : '+downloadData.parms.xmin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.xTitle+'", "value" : {"$lte" : '+downloadData.parms.xmax+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$gte" : '+downloadData.parms.ymin+'}}}}}},{"properties.scalar_features":{"$elemMatch":{"nv":{"$elemMatch":{"name" : "'+downloadData.parms.yTitle+'", "value" : {"$lte" : '+downloadData.parms.ymax+'}}}}}}],')
     downloadData.parms.urlFind=findQuery()

     downloadButton.onclick=function(){
         downloadButton.disabled=true
         downloadButton.textContent='Downloading ...'
         downloadData.msg('preparing download ...','red')
         // first find out what fields are there to retrieve
         /*
         var getFields=function(){
             var x = downloadData.propertiesArray(downloadData.parms.x)
         }
         getFields()
         */
         downloadData.getData()

     }
	 /*
     saveFileJsonBt.onclick=function(){

         jmat.saveFile(JSON.stringify(downloadData.dt),'features.json')
     }
	 */

     saveFileCsvBt.onclick=function(){
         var ff = Object.getOwnPropertyNames(downloadData.dt[0]).sort()
         var csv=ff.join(',')+'\n' // header
         downloadData.dt.forEach(function(r){
             var x = []
             ff.forEach(function(f){
                 x.push(r[f])
             })
             csv+=x.join(',')+'\n'
         })
         jmat.saveFile(csv.slice(0,-1),'features.csv')

     }

}

downloadData.propertiesArray=function(x){ // convert ns in an awway into an arra of ns
    return x.map(function(xi){
        var y = {}
        xi = xi.properties.scalar_features[0].nv.forEach(function(z){
            y[z.name]=z.value
        })
        return y
    })
}

downloadData.getParms=function(){ // extract parameters from url search
    downloadData.parms=downloadData.parms||{}
    location.search.slice(1).split('&')
     .forEach(function(pp){
         pp = pp.split('=')
         downloadData.parms[pp[0]]=decodeURIComponent(decodeURIComponent(pp[1]))
     })
    //var pp = decodeURIComponent(decodeURIComponent(location.search)).slice(1)
}

// get the data

downloadData.dataTabling=function(){
    //saveFileJsonBt.textContent='Save File as JSON'
    saveFileCsvBt.textContent='Save File as CSV'
    var div = document.getElementById('dataTabling')|| document.createElement('div')
    div.id='dataTabling'
    div.innerHTML='
Variables:

<button class="btn btn-success" id="showhideData">tabulate data</button>

'
    downloadDataDiv.appendChild(div)
    downloadData.fieldsChecked=[]
    if(downloadData.dt.length>0){
        downloadData.fields=Object.getOwnPropertyNames(downloadData.dt[0]).sort()
        downloadData.fields.forEach(function(p,i){
            var sp = document.createElement('span')
            var ip = document.createElement('input')
            ip.type='radio'
            ip.value=p
            if(i<3){
                ip.checked=true
                ip.nocheck=false
                downloadData.fieldsChecked.push(p)
            } else {
                ip.checked=false
                ip.nocheck=true
            }
            var h = ' '+p
            sp.innerHTML = h
            sp.appendChild(ip)
            sp.style.color='navy'
            tableVars.appendChild(sp)
            ip.onclick=function(){
                this.nocheck=!this.nocheck
                this.checked=!this.nocheck
                if(this.nocheck){
                    downloadData.fieldsChecked.pop(downloadData.fieldsChecked.indexOf(this.value))
                } else {
                    downloadData.fieldsChecked.push(this.value) // add to list of selected fields
                }
                console.log(downloadData.fieldsChecked)
            }
        })
    }
    showhideData.onclick=function(){
        var div = document.getElementById('tableData')
        div.innerHTML='' // clear if something is there
        div.appendChild(downloadData.docs2html(downloadData.dt,downloadData.fieldsChecked))
    }

    4
}

downloadData.docs2html=function(docs,parms){
    parms = parms || Object.getOwnPropertyNames(docs[0])
    var tb = document.createElement('table')
    tb.cellSpacing='5px'
    var th = document.createElement('thead')
    tb.appendChild(th)
    var trh = document.createElement('tr')
    trh.style.fontSize='10px'
    trh.style.color='navy'
    th.appendChild(trh)
    parms.forEach(function(p){
        var td = document.createElement('td')
        td.textContent=p
        td.style.padding='3px'
        trh.appendChild(td)
    })
    var tbd = document.createElement('tbody')
    tb.appendChild(tbd)

    docs.forEach(function(d){
        var tr = document.createElement('tr')
        tr.style.fontSize='10px'
        tbd.appendChild(tr)
        parms.forEach(function(p){
            var td = document.createElement('td')
            td.style.padding='3px'
            td.textContent=d[p]
            tr.appendChild(td)
            4
        })
    })
    return tb
}

downloadData.getData=function(){
    var n =  1000 // at a time
    if(!downloadData.dt){downloadData.dt=[]}
    //if(!downloadData.parms.n){downloadData.parms.n=0}
    if(!downloadData.parms.lastId){
        var url= downloadData.parms.urlFind+'&limit='+n
    }else{
        //var url=downloadData.parms.urlFind.replace('find={','find={"_id":{"$gt":"'+downloadData.parms.lastId+'"},')+'&limit='+n
        var url= downloadData.parms.urlFind+'&limit='+n+'&offset="'+downloadData.parms.lastId+'"'
    }
    //url = url.replace('http://quip1.uhmc.sunysb.edu','http://129.49.249.191')
    $.getJSON(url)
     .then(function(x){
         try{
             if(!Array.isArray(x)){x=[]}
             //downloadData.parms.n+=x.length
             if(x.length>0){
                 downloadData.parms.lastId=x.slice(-1)[0]._id
                 downloadData.dt=downloadData.dt.concat(downloadData.propertiesArray(x))
                 console.log(Date()+' n = '+downloadData.dt.length+', last _id = '+downloadData.parms.lastId)
             }
             downloadData.msg('features retrieved so far: '+downloadData.dt.length+' out of an estimated total of '+downloadData.parms.pn+' ...','orange')
             if((x.length==n)&(x.length<parseInt(downloadDataLimitInput.value))){
                 setTimeout(function(){
                    //downloadData.parms.urlFind = downloadData.parms.urlFind.replace('http://quip1.uhmc.sunysb.edu','http://129.49.249.191')
                    downloadData.getData()
                 },1000)
             }else{
                 downloadData.dt=downloadData.dt.slice(0,Math.min(downloadData.dt.length,parseInt(downloadDataLimitInput.value)))
                 var N=downloadData.dt.length
                 var M=Object.getOwnPropertyNames(downloadData.dt[0]).length
                 downloadData.msg('Data retrieval ended, '+N+' x '+M+' = '+(N*M)+' values retrieved','green') //, it can be resumed by clicking on Download','green')
                 downloadButton.disabled=false
                 downloadButton.textContent='New Download'
                 downloadButton.style.backgroundColor='orange'
                 downloadButton.style.color='green'
                 downloadButton.onclick=function(){
                     window.open(location.href)
                 }
                 // make data tables available
                 downloadData.dataTabling()
             }
             //saveFileJsonBt.disabled=false
             saveFileCsvBt.disabled=false
         }
         catch(err){
             console.log(Date()+' error:',x)
             setTimeout(function(){
                 downloadData.getData()
             },1000)

         }

     })
     .fail(function(err){
         downloadData.msg('Connection Error :-( ','red')
     })

    4
}

// Run
if(document.getElementById('downloadDataDiv')){
    downloadData(downloadDataDiv)
}
window.onload=function(){
    if(document.getElementById('downloadDataDiv')){
        downloadData(downloadDataDiv)
    }
}

/*
example
http://quip1.uhmc.sunysb.edu:3000/?limit=1000&find={%22randval%22:{%22$gte%22:0.17426561033975674},%22provenance.analysis.execution_id%22:%22luad:bg:20160520%22,%22provenance.image.case_id%22:%22TCGA-55-6543-01Z-00-DX1%22}&db=u24_luad

*/<|endoftext|>