<commit_before>/*!
 * Event Burrito is a touch / mouse / pointer event unifier
 * https://github.com/wilddeer/Event-Burrito
 * Copyright Oleg Korsunsky | http://wd.dizaina.net/
 *
 * MIT License
 *
 * NOTE: Event Burrito has been modified from
 * its original form to suit this project.
 */

/* exported TouchEvents */

function TouchEvents(_this, options) {
  'use strict';

  const touchStateCallback = () => {},
    o = {
      preventDefault: true,
      clicksAllowed: true,
      mouse: true,
      dragThreshold: 10, // Minimum distance to determine swipe direction
      start: touchStateCallback,
      move: touchStateCallback,
      end: touchStateCallback
    };

  // Merge user options into defaults
  options && mergeObjects(o, options);

  let start = {},
    diff = {},
    direction,
    eventType,
    axis,
    support = {
      pointerEvents: !!window.navigator.pointerEnabled,
      msPointerEvents: !!window.navigator.msPointerEnabled
    },
    eventModel = (support.pointerEvents ? 1 : (support.msPointerEvents ? 2 : 0)),
    events = [
      ['touchstart', 'touchmove', 'touchend', 'touchcancel'], //touch events
      ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'], //pointer events
      ['MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel'], //IE10 pointer events
      ['mousedown', 'mousemove', 'mouseup', false] //mouse events
    ],
    checks = [
      //touch events
      (e) =>{
        //skip the event if it's multitouch or pinch move
        return (e.touches && e.touches.length > 1) || (e.scale && e.scale !== 1);
      },
      //pointer events
      (e) => {
        //Skip it, if:
        //1. event is not primary (other pointers during multitouch),
        //2. left mouse button is not pressed,
        //3. mouse drag is disabled and event is not touch
        return !e.isPrimary || (e.buttons && e.buttons !== 1) || (!o.mouse && e.pointerType !== 'touch' && e.pointerType !== 'pen');
      },
      //IE10 pointer events
      (e) => {
        //same checks as in pointer events
        return !e.isPrimary || (e.buttons && e.buttons !== 1) || (!o.mouse && e.pointerType !== e.MSPOINTER_TYPE_TOUCH && e.pointerType !== e.MSPOINTER_TYPE_PEN);
      },
      //mouse events
      (e) => {
        //skip the event if left mouse button is not pressed
        //in IE7-8 `buttons` is not defined, in IE9 LMB is 0
        return (e.buttons && e.buttons !== 1);
      }
    ];

  function mergeObjects(targetObj, sourceObject) {
    for (let key in sourceObject) {
      if (sourceObject.hasOwnProperty(key)) {
        targetObj[key] = sourceObject[key];
      }
    }
  }

  function addEvent(el, event, func, bool) {
    if (!event) return;
    el.addEventListener(event, func, !!bool);
  }

  function removeEvent(el, event, func, bool) {
    if (!event) return;
    el.removeEventListener(event, func, !!bool);
  }

  function preventDefault(event) {
    event.preventDefault ? event.preventDefault() : event.returnValue = false;
  }

  function getDiff(event) {
    diff = {
      X: (eventType ? event.clientX : event.touches[0].clientX) - start.X,
      Y: (eventType ? event.clientY : event.touches[0].clientY) - start.Y,
      time: new Date().getTime() - start.time
    };
  }

  function touchStart(event, type) {
    direction = '';
    o.clicksAllowed = true;
    eventType = type;

    if (checks[eventType](event)) return;

    if (preventDefault && eventType) preventDefault(event);

    addEvent(document, events[eventType][1], touchMove);
    addEvent(document, events[eventType][2], touchEnd);
    addEvent(document, events[eventType][3], touchEnd);

    start = {
      X: eventType ? event.clientX : event.touches[0].clientX,
      Y: eventType ? event.clientY : event.touches[0].clientY,
      time: new Date().getTime()
    };

    for (let key in diff) {
      diff[key] = 0;
    }
    o.start(event);
  }

  function touchMove(event) {
    getDiff(event);

    //Prevent document from scrolling while swiping because
    //mobile browsers flicker during transition.
    document.ontouchmove = (e) => { preventDefault(e); }

    if (!axis) {
      axis = (o.dragThreshold < Math.abs(diff.X)) ? 'X' : (o.dragThreshold < Math.abs(diff.Y)) ? 'Y' : false;
    } else {
      if (axis === 'X') {
        direction = (diff.X < 0) ? 'left' : 'right';
        preventDefault && preventDefault(event);
      } else if (axis === 'Y') {
        direction = (diff.Y < 0) ? 'up' : 'down';
      }
    }

    o.move(event, direction, diff);
  }

  function touchEnd(event) {
    !o.clicksAllowed && event.target && event.target.blur && event.target.blur();

    removeEvent(document, events[eventType][1], touchMove);
    removeEvent(document, events[eventType][2], touchEnd);
    removeEvent(document, events[eventType][3], touchEnd);

    //Enable document scrolling.
    document.ontouchmove = (e) => { return true; }

    o.end(event, direction, diff);
    axis = false;
  }

  function init() {
    // Bind touchstart
    addEvent(_this, events[eventModel][0], (event) => {
      touchStart(event, eventModel);
    });
    // Prevent stuff from dragging when using mouse
    addEvent(_this, 'dragstart', preventDefault);

    // Bind mousedown if necessary
    if (o.mouse && !eventModel) {
      addEvent(_this, events[3][0], (event) => {
        touchStart(event, 3);
      });
    }

    // No clicking during touch
    addEvent(_this, 'click', (event) => {
      o.clicksAllowed ? touchStateCallback(event) : preventDefault(event);
    });
  }

  // Init touch listeners
  init();
}<commit_msg>Fix lint issues with missing semicolons<commit_after>/*!
 * Event Burrito is a touch / mouse / pointer event unifier
 * https://github.com/wilddeer/Event-Burrito
 * Copyright Oleg Korsunsky | http://wd.dizaina.net/
 *
 * MIT License
 *
 * NOTE: Event Burrito has been modified from
 * its original form to suit this project.
 */

/* exported TouchEvents */

function TouchEvents(_this, options) {
  'use strict';

  const touchStateCallback = () => {},
    o = {
      preventDefault: true,
      clicksAllowed: true,
      mouse: true,
      dragThreshold: 10, // Minimum distance to determine swipe direction
      start: touchStateCallback,
      move: touchStateCallback,
      end: touchStateCallback
    };

  // Merge user options into defaults
  options && mergeObjects(o, options);

  let start = {},
    diff = {},
    direction,
    eventType,
    axis,
    support = {
      pointerEvents: !!window.navigator.pointerEnabled,
      msPointerEvents: !!window.navigator.msPointerEnabled
    },
    eventModel = (support.pointerEvents ? 1 : (support.msPointerEvents ? 2 : 0)),
    events = [
      ['touchstart', 'touchmove', 'touchend', 'touchcancel'], //touch events
      ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'], //pointer events
      ['MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel'], //IE10 pointer events
      ['mousedown', 'mousemove', 'mouseup', false] //mouse events
    ],
    checks = [
      //touch events
      (e) =>{
        //skip the event if it's multitouch or pinch move
        return (e.touches && e.touches.length > 1) || (e.scale && e.scale !== 1);
      },
      //pointer events
      (e) => {
        //Skip it, if:
        //1. event is not primary (other pointers during multitouch),
        //2. left mouse button is not pressed,
        //3. mouse drag is disabled and event is not touch
        return !e.isPrimary || (e.buttons && e.buttons !== 1) || (!o.mouse && e.pointerType !== 'touch' && e.pointerType !== 'pen');
      },
      //IE10 pointer events
      (e) => {
        //same checks as in pointer events
        return !e.isPrimary || (e.buttons && e.buttons !== 1) || (!o.mouse && e.pointerType !== e.MSPOINTER_TYPE_TOUCH && e.pointerType !== e.MSPOINTER_TYPE_PEN);
      },
      //mouse events
      (e) => {
        //skip the event if left mouse button is not pressed
        //in IE7-8 `buttons` is not defined, in IE9 LMB is 0
        return (e.buttons && e.buttons !== 1);
      }
    ];

  function mergeObjects(targetObj, sourceObject) {
    for (let key in sourceObject) {
      if (sourceObject.hasOwnProperty(key)) {
        targetObj[key] = sourceObject[key];
      }
    }
  }

  function addEvent(el, event, func, bool) {
    if (!event) return;
    el.addEventListener(event, func, !!bool);
  }

  function removeEvent(el, event, func, bool) {
    if (!event) return;
    el.removeEventListener(event, func, !!bool);
  }

  function preventDefault(event) {
    event.preventDefault ? event.preventDefault() : event.returnValue = false;
  }

  function getDiff(event) {
    diff = {
      X: (eventType ? event.clientX : event.touches[0].clientX) - start.X,
      Y: (eventType ? event.clientY : event.touches[0].clientY) - start.Y,
      time: new Date().getTime() - start.time
    };
  }

  function touchStart(event, type) {
    direction = '';
    o.clicksAllowed = true;
    eventType = type;

    if (checks[eventType](event)) return;

    if (preventDefault && eventType) preventDefault(event);

    addEvent(document, events[eventType][1], touchMove);
    addEvent(document, events[eventType][2], touchEnd);
    addEvent(document, events[eventType][3], touchEnd);

    start = {
      X: eventType ? event.clientX : event.touches[0].clientX,
      Y: eventType ? event.clientY : event.touches[0].clientY,
      time: new Date().getTime()
    };

    for (let key in diff) {
      diff[key] = 0;
    }
    o.start(event);
  }

  function touchMove(event) {
    getDiff(event);

    //Prevent document from scrolling while swiping because
    //mobile browsers flicker during transition.
    document.ontouchmove = (e) => { preventDefault(e); };

    if (!axis) {
      axis = (o.dragThreshold < Math.abs(diff.X)) ? 'X' : (o.dragThreshold < Math.abs(diff.Y)) ? 'Y' : false;
    } else {
      if (axis === 'X') {
        direction = (diff.X < 0) ? 'left' : 'right';
        preventDefault && preventDefault(event);
      } else if (axis === 'Y') {
        direction = (diff.Y < 0) ? 'up' : 'down';
      }
    }

    o.move(event, direction, diff);
  }

  function touchEnd(event) {
    !o.clicksAllowed && event.target && event.target.blur && event.target.blur();

    removeEvent(document, events[eventType][1], touchMove);
    removeEvent(document, events[eventType][2], touchEnd);
    removeEvent(document, events[eventType][3], touchEnd);

    //Enable document scrolling.
    document.ontouchmove = (e) => { return true; };

    o.end(event, direction, diff);
    axis = false;
  }

  function init() {
    // Bind touchstart
    addEvent(_this, events[eventModel][0], (event) => {
      touchStart(event, eventModel);
    });
    // Prevent stuff from dragging when using mouse
    addEvent(_this, 'dragstart', preventDefault);

    // Bind mousedown if necessary
    if (o.mouse && !eventModel) {
      addEvent(_this, events[3][0], (event) => {
        touchStart(event, 3);
      });
    }

    // No clicking during touch
    addEvent(_this, 'click', (event) => {
      o.clicksAllowed ? touchStateCallback(event) : preventDefault(event);
    });
  }

  // Init touch listeners
  init();
}<|endoftext|>


<commit_before>var path = require('path');
var webserver = require('gulp-webserver');
var _ = require('underscore');
var gulp = require('gulp');
var gutil = require('gulp-util');
var s3 = require('gulp-s3');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var prettify = require('gulp-prettify');
var webpack = require('gulp-webpack');
var plumber = require('gulp-plumber');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var sitemap = require('gulp-sitemap');

require('node-jsx').install();

require('react-a11y')();

var IndexFileStream = require('./lib/gulp-index-file-stream');
var webpackConfig = require('./webpack.config');

var BUILD_TASKS = [
  'copy-test-dirs',
  'copy-dirs',
  'less',
  'webpack',
  'sitemap',
  'generate-index-files'
];

var COPY_DIRS = [
  'img/**',
  'vendor/bootstrap/css/**',
  'vendor/bootstrap/fonts/**',
];

var LESS_FILES = './less/**/*.less';

function onError(err) {
  gutil.log(gutil.colors.red(err));
  gutil.beep();
  this.emit('end');
}

function handleError() {
  return plumber({
    errorHandler: onError
  });
}

gulp.task('sitemap', function() {
  gulp.src('dist/**/*.html')
    .pipe(sitemap({
      siteUrl: process.env.ORIGIN || 'https://teach.webmaker.org'
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('copy-test-dirs', function() {
  return merge(
    gulp.src('test/browser/static/**', {
      base: './test/browser/static'
    }),
    gulp.src('node_modules/mocha/mocha.*', {
      base: './node_modules/mocha'
    })
  ).pipe(gulp.dest('./dist/test'));
});

gulp.task('copy-dirs', function() {
  return gulp.src(COPY_DIRS, {
    base: '.'
  }).pipe(gulp.dest('./dist'));
});

gulp.task('less', function() {
  return gulp.src(LESS_FILES)
    .pipe(handleError())
    .pipe(sourcemaps.init())
    .pipe(less({
      paths: [path.join(__dirname, 'less')]
    }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(webpackConfig))
    .pipe(gulp.dest('./dist'));
});

gulp.task('smoketest', BUILD_TASKS.concat([
  'test-react-warnings'
]), function() {
  gutil.log(gutil.colors.green.bold("Yay, smoke test passes!"));
});

gulp.task('test-react-warnings', function() {
  var oldWarn = console.warn;
  var warnings = 0;

  console.warn = function(message) {
    warnings++;
    gutil.log(gutil.colors.red.bold(message));
  };

  return new IndexFileStream(require('./lib/index-static.jsx'))
    .on('end', function() {
      console.warn = oldWarn;
      if (warnings) {
        this.emit('error', new Error('At least one warning was logged.'));
      }
    })
    .pipe(gulp.dest('./dist'));
});

gulp.task('generate-index-files', function() {
  return new IndexFileStream(require('./lib/index-static.jsx'))
    .pipe(prettify({
      indent_size: 2
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('default', BUILD_TASKS);

gulp.task('watch', _.without(BUILD_TASKS, 'webpack'), function(cb) {
  gulp.src(webpackConfig.entry.app)
    .pipe(webpack(_.extend({
      watch: true
    }, webpackConfig)))
    .pipe(gulp.dest('./dist'));

  gulp.watch([
    'lib/**'
  ], function() {
    gutil.log('Rebuilding index HTML files.');

    // Ugh, because the *old* version of our index files are
    // already in node's require cache, we can't reload them, so
    // we'll run gulp in a subprocess so that it uses the latest
    // code.
    //
    // TODO: Figure out a better solution for this.
    require('child_process')
      .exec('gulp generate-index-files', function(err, stdout, stderr) {
        if (err) {
          gutil.log(gutil.colors.red.bold("Error rebuilding index files!"));
          gutil.log(stdout);
          gutil.log(stderr);
        } else {
          gutil.log("Index HTML files rebuilt.");
        }
      });
  });

  gulp.watch(COPY_DIRS, ['copy-dirs']);
  gulp.watch(LESS_FILES, ['less']);
  gulp.watch('test/browser/static/**', ['copy-test-dirs']);

  gulp.src('dist')
    .pipe(webserver({
      livereload: {
        enable: true
      },
      port: 8008
    }));
});

gulp.task('s3', BUILD_TASKS, function() {
  var key = process.env.AWS_ACCESS_KEY;
  var secret = process.env.AWS_SECRET_KEY;

  if (!key || !secret)
    throw new Error('Please set AWS_ACCESS_KEY and AWS_SECRET_KEY ' +
      'in your environment.');

  return gulp.src('./dist/**')
    .pipe(gzip())
    .pipe(s3({
      key: key,
      secret: secret,
      bucket: process.env.AWS_BUCKET || 'teach.mofostaging.net',
      region: process.env.AWS_REGION || 'us-east-1'
    }, {
      gzippedOnly: true,
      headers: {
        'Cache-Control': 'max-age=600, public'
      }
    }));
});
<commit_msg>Sitemap watch<commit_after>var path = require('path');
var webserver = require('gulp-webserver');
var _ = require('underscore');
var gulp = require('gulp');
var gutil = require('gulp-util');
var s3 = require('gulp-s3');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var prettify = require('gulp-prettify');
var webpack = require('gulp-webpack');
var plumber = require('gulp-plumber');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var sitemap = require('gulp-sitemap');

require('node-jsx').install();

require('react-a11y')();

var IndexFileStream = require('./lib/gulp-index-file-stream');
var webpackConfig = require('./webpack.config');

var BUILD_TASKS = [
  'copy-test-dirs',
  'copy-dirs',
  'less',
  'webpack',
  'generate-index-files',
  'sitemap'
];

var COPY_DIRS = [
  'img/**',
  'vendor/bootstrap/css/**',
  'vendor/bootstrap/fonts/**',
];

var LESS_FILES = './less/**/*.less';

function onError(err) {
  gutil.log(gutil.colors.red(err));
  gutil.beep();
  this.emit('end');
}

function handleError() {
  return plumber({
    errorHandler: onError
  });
}

gulp.task('sitemap', function() {
  gulp.src('dist/**/*.html')
    .pipe(sitemap({
      siteUrl: process.env.ORIGIN || 'https://teach.webmaker.org'
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('copy-test-dirs', function() {
  return merge(
    gulp.src('test/browser/static/**', {
      base: './test/browser/static'
    }),
    gulp.src('node_modules/mocha/mocha.*', {
      base: './node_modules/mocha'
    })
  ).pipe(gulp.dest('./dist/test'));
});

gulp.task('copy-dirs', function() {
  return gulp.src(COPY_DIRS, {
    base: '.'
  }).pipe(gulp.dest('./dist'));
});

gulp.task('less', function() {
  return gulp.src(LESS_FILES)
    .pipe(handleError())
    .pipe(sourcemaps.init())
    .pipe(less({
      paths: [path.join(__dirname, 'less')]
    }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(webpackConfig))
    .pipe(gulp.dest('./dist'));
});

gulp.task('smoketest', BUILD_TASKS.concat([
  'test-react-warnings'
]), function() {
  gutil.log(gutil.colors.green.bold("Yay, smoke test passes!"));
});

gulp.task('test-react-warnings', function() {
  var oldWarn = console.warn;
  var warnings = 0;

  console.warn = function(message) {
    warnings++;
    gutil.log(gutil.colors.red.bold(message));
  };

  return new IndexFileStream(require('./lib/index-static.jsx'))
    .on('end', function() {
      console.warn = oldWarn;
      if (warnings) {
        this.emit('error', new Error('At least one warning was logged.'));
      }
    })
    .pipe(gulp.dest('./dist'));
});

gulp.task('generate-index-files', function() {
  return new IndexFileStream(require('./lib/index-static.jsx'))
    .pipe(prettify({
      indent_size: 2
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('default', BUILD_TASKS);

gulp.task('watch', _.without(BUILD_TASKS, 'webpack'), function(cb) {
  gulp.src(webpackConfig.entry.app)
    .pipe(webpack(_.extend({
      watch: true
    }, webpackConfig)))
    .pipe(gulp.dest('./dist'));

  gulp.watch([
    'lib/**'
  ], function() {
    gutil.log('Rebuilding index HTML files.');

    // Ugh, because the *old* version of our index files are
    // already in node's require cache, we can't reload them, so
    // we'll run gulp in a subprocess so that it uses the latest
    // code.
    //
    // TODO: Figure out a better solution for this.
    require('child_process')
      .exec('gulp generate-index-files', function(err, stdout, stderr) {
        if (err) {
          gutil.log(gutil.colors.red.bold("Error rebuilding index files!"));
          gutil.log(stdout);
          gutil.log(stderr);
        } else {
          gutil.log("Index HTML files rebuilt.");
        }
      });
  });

  gulp.watch(COPY_DIRS, ['copy-dirs']);
  gulp.watch(LESS_FILES, ['less']);
  gulp.watch('test/browser/static/**', ['copy-test-dirs']);
  gulp.watch('dist/**/*.html', ['sitemap']);

  gulp.src('dist')
    .pipe(webserver({
      livereload: {
        enable: true
      },
      port: 8008
    }));
});

gulp.task('s3', BUILD_TASKS, function() {
  var key = process.env.AWS_ACCESS_KEY;
  var secret = process.env.AWS_SECRET_KEY;

  if (!key || !secret)
    throw new Error('Please set AWS_ACCESS_KEY and AWS_SECRET_KEY ' +
      'in your environment.');

  return gulp.src('./dist/**')
    .pipe(gzip())
    .pipe(s3({
      key: key,
      secret: secret,
      bucket: process.env.AWS_BUCKET || 'teach.mofostaging.net',
      region: process.env.AWS_REGION || 'us-east-1'
    }, {
      gzippedOnly: true,
      headers: {
        'Cache-Control': 'max-age=600, public'
      }
    }));
});
<|endoftext|>


<commit_before>// node
// vendors
import React from 'react';
// project
import Menu from './components/menu';

import { Button } from 'react-bootstrap';

import './styles.scss';

const App = () => (

Hello, World!

    <Menu />
    <Button bsStyle="success">Success</Button>

);

export default App;
<commit_msg>fix using simple quote<commit_after>// node
// vendors
import React from 'react';
// project
import Menu from './components/menu';

import { Button } from 'react-bootstrap';

import './styles.scss';

const App = () => (

Hello, World!

    <Menu />
    <Button bsStyle='success'>Success</Button>

);

export default App;
<|endoftext|>


<commit_before>require.config({
	baseUrl : "./",
	paths : {
		"knockout" : "scripts/lib/knockout-3.0.0",
		"knockout-amd-helpers" : "scripts/lib/knockout-amd-helpers",
		"knockout-postbox" : "scripts/lib/knockout-postbox",
		"text" : "scripts/lib/text",
		"jquery" : "scripts/lib/jquery-1.9.1.min",
		"jquery-ui" : "scripts/lib/jquery-ui-1.10.3.custom.min",
		"knockout-jqueryui" : "scripts/lib/knockout-jqueryui.min"
	}
});

require([ "knockout","jquery", "scripts/modules/topicexplorer-view-model",
		"knockout-amd-helpers", "knockout-postbox",
		"text", "jquery-ui", "knockout-jqueryui" ], function(ko, $, App) {
	var timeoutId = null;
	var self=this;
	ko.bindingHandlers.module.baseDir = "scripts/modules";

	// global delegates
	$(document).delegate(".menuActivator", 'click', function(e){
		if($(this).next().height() + 26 > $(this).parent().height()) {
	    	$(this).next().css('max-height', $(this).parent().height() - 26);
	    }

		$(this).toggleClass("rotate1 rotate2");
	    $(this).next().toggle('blind');

	}).delegate("#invisbleTabs > span", 'click', function() {
		$('#tabMenu').toggle('blind');
	}).delegate("a.ui-corner-all", 'mouseover', function() {
		$(this).addClass('ui-state-focus');
	}).delegate("a.ui-corner-all", 'mouseout', function() {
		$(this).removeClass('ui-state-focus');
	}).delegate(".tab", 'mouseover', function() {
		$(this).children('img').show();
	}).delegate(".tab", 'mouseout', function() {
		$(this).children('img').hide();
	}).delegate(".documentList li", 'mouseenter', function(){
		$(this).addClass('myHover').find(".docButtons").show();
	}).delegate(".documentList li", 'mouseleave', function(){
		$(this).removeClass('myHover').find(".docButtons").hide();
	}).delegate(".documentList circle", "mouseover", function(){
		$(this).attr("r", "7");
	}).delegate(".documentList circle", "mouseout", function(){
		$(this).attr("r", "5");
	}).delegate(".ui-menu-item circle", "mouseover", function(){
		var self = this;
		if (!timeoutId) {
	        timeoutId = window.setTimeout(function() {
	            timeoutId = null;
	            moveToTopic($(self).attr('id').split('_')[1]);
		    }, 1500);
		}
		$(self).attr("r", "7");
	}).delegate(".ui-menu-item circle", "mouseout", function(){
		if (timeoutId) {
		    window.clearTimeout(timeoutId);
		    timeoutId = null;
		}
		$(this).attr("r", "5");
	}).delegate("#groupG rect", "mouseover", function(){
		$(this).attr("height", "17");
		$(this).attr("y", "0");
	}).delegate("#groupG rect", "mouseout", function(){
		$(this).attr("height", "13");
		$(this).attr("y", "2");
	}).delegate(".topicList", "mouseenter", function(){
		$(this).children(":first").show();
	}).delegate("#desktop", "mouseenter", function(){
		$(this).children(":first").show();
		if($("#desktop").scrollTop() > 1000) {
			$("#jumpToStart").show();
		}
	}).delegate("#desktop, .topicList", "mouseleave", function(){
		$(this).children(":first").hide();
		$(this).children(":first").next().hide();
		$(this).children(":first").removeClass("rotate2");
		$(this).children(":first").addClass("rotate1");
		$("#jumpToStart").hide();
	}).delegate("#jumpToStart", "click", function() {
		$("#desktop").animate({
			scrollTop: 0
		});
	}).delegate(".documentList circle, #groupG rect", "click", moveToTopic);

	self.minHeight = 400;
	self.minWidth = 800;

	$(window).resize(function() {
		ko.postbox.publish("windowWidth",Math.max(self.minWidth, $(window).width(), /* For opera: */ document.documentElement.clientWidth));
		ko.postbox.publish("windowHeight",Math.max(self.minHeight, $(window).height(), /* For opera: */ document.documentElement.clientHeight));
		setTopicSlider();
	});

	setTimeout(function() {
		ko.applyBindings(new App());
	}, 0);

	setTimeout(function() {
		ko.postbox.publish("windowWidth",Math.max(self.minWidth, $(window).width(), /* For opera: */ document.documentElement.clientWidth));
		ko.postbox.publish("windowHeight",Math.max(self.minHeight, $(window).height(), /* For opera: */ document.documentElement.clientHeight));
		setTopicSlider();
	}, 1500);

});

function setTopicSlider() {
	var slider = $('.topicPrevSlider');
	var maxListWidth = $('.topicList > ul').width();
	var topicDivWidth = $('.topicList').width();
	var bottomDivWidth = $('.topicBottomSliderDiv').width();

	slider.width((topicDivWidth*bottomDivWidth)/ maxListWidth);

	$('.topicPrevSlider > span').css('margin-left', (topicDivWidth * bottomDivWidth) / (maxListWidth * 2) - ($('.topicPrevSlider > span').width() / 2));
	var maxScrollPos = $('.topicBottomSliderDiv').width() - $('.topicPrevSlider').width();
	$( ".topicPrevSlider" ).draggable({
		axis: "x",
		containment: [ 0, 0, maxScrollPos, 0 ],
		drag: function( event, ui ) {
			var maxScroll = (maxListWidth - topicDivWidth);
			var scroll = ((ui.position.left + 4) / maxScrollPos) * maxScroll ;
			$('.topicList').scrollLeft(scroll);
			$('#topicMenu, .topicList > img').css('left', scroll);
		}
	});
};

function makeMenu(el) {
	$(el).menu({
		select : function(event, ui) {
			$(this).parent().parent().prev()
				.toggleClass("rotate1 rotate2");
			$(this).parent().parent().toggle('blind');
		}
	});
};

function getScrollPositionByValue(val) {
	var offset = 3;
	var scroll = val;
	var maxScrollPos = $('.topicBottomSliderDiv').width() - $('.topicPrevSlider').width();
	var maxScroll = $('.topicList > ul').width() - $('.topicList').width();
	var position = Math.round(scroll*maxScrollPos/maxScroll)+offset;
	if(position < 0)
		position = 0;
	if(position > maxScrollPos)
		position = maxScrollPos;
	return position;
};

function moveToTopic(self) {

	var topic_id = 0;
	if(!self.currentTarget) {
		topic_id = self;
	} else {
		topic_id = $(self.currentTarget).attr('id').split("_")[1];
	}
	var offset = $(".topicList").width() / 2 - $("#topic" + topic_id).width() / 2;

	$(".topicList").animate({
		scrollLeft : ($("#topic" + topic_id).position().left - offset)
	}, {
		duration : 2000,
		easing : "swing"
	});
	$(".topicPrevSlider").animate({
		left : getScrollPositionByValue(($("#topic" + topic_id).position().left - offset))
	}, {
		duration : 2000,
		easing : "swing"
	});
	setTimeout(function() {
		$(".topicList > img, #topicMenu").css('left', $(".topicList").scrollLeft());
	}, 2000);
};

<commit_msg>#5 increment initial loading time<commit_after>require.config({
	baseUrl : "./",
	paths : {
		"knockout" : "scripts/lib/knockout-3.0.0",
		"knockout-amd-helpers" : "scripts/lib/knockout-amd-helpers",
		"knockout-postbox" : "scripts/lib/knockout-postbox",
		"text" : "scripts/lib/text",
		"jquery" : "scripts/lib/jquery-1.9.1.min",
		"jquery-ui" : "scripts/lib/jquery-ui-1.10.3.custom.min",
		"knockout-jqueryui" : "scripts/lib/knockout-jqueryui.min"
	}
});

require([ "knockout","jquery", "scripts/modules/topicexplorer-view-model",
		"knockout-amd-helpers", "knockout-postbox",
		"text", "jquery-ui", "knockout-jqueryui" ], function(ko, $, App) {
	var timeoutId = null;
	var self=this;
	ko.bindingHandlers.module.baseDir = "scripts/modules";

	// global delegates
	$(document).delegate(".menuActivator", 'click', function(e){
		if($(this).next().height() + 26 > $(this).parent().height()) {
	    	$(this).next().css('max-height', $(this).parent().height() - 26);
	    }

		$(this).toggleClass("rotate1 rotate2");
	    $(this).next().toggle('blind');

	}).delegate("#invisbleTabs > span", 'click', function() {
		$('#tabMenu').toggle('blind');
	}).delegate("a.ui-corner-all", 'mouseover', function() {
		$(this).addClass('ui-state-focus');
	}).delegate("a.ui-corner-all", 'mouseout', function() {
		$(this).removeClass('ui-state-focus');
	}).delegate(".tab", 'mouseover', function() {
		$(this).children('img').show();
	}).delegate(".tab", 'mouseout', function() {
		$(this).children('img').hide();
	}).delegate(".documentList li", 'mouseenter', function(){
		$(this).addClass('myHover').find(".docButtons").show();
	}).delegate(".documentList li", 'mouseleave', function(){
		$(this).removeClass('myHover').find(".docButtons").hide();
	}).delegate(".documentList circle", "mouseover", function(){
		$(this).attr("r", "7");
	}).delegate(".documentList circle", "mouseout", function(){
		$(this).attr("r", "5");
	}).delegate(".ui-menu-item circle", "mouseover", function(){
		var self = this;
		if (!timeoutId) {
	        timeoutId = window.setTimeout(function() {
	            timeoutId = null;
	            moveToTopic($(self).attr('id').split('_')[1]);
		    }, 1500);
		}
		$(self).attr("r", "7");
	}).delegate(".ui-menu-item circle", "mouseout", function(){
		if (timeoutId) {
		    window.clearTimeout(timeoutId);
		    timeoutId = null;
		}
		$(this).attr("r", "5");
	}).delegate("#groupG rect", "mouseover", function(){
		$(this).attr("height", "17");
		$(this).attr("y", "0");
	}).delegate("#groupG rect", "mouseout", function(){
		$(this).attr("height", "13");
		$(this).attr("y", "2");
	}).delegate(".topicList", "mouseenter", function(){
		$(this).children(":first").show();
	}).delegate("#desktop", "mouseenter", function(){
		$(this).children(":first").show();
		if($("#desktop").scrollTop() > 1000) {
			$("#jumpToStart").show();
		}
	}).delegate("#desktop, .topicList", "mouseleave", function(){
		$(this).children(":first").hide();
		$(this).children(":first").next().hide();
		$(this).children(":first").removeClass("rotate2");
		$(this).children(":first").addClass("rotate1");
		$("#jumpToStart").hide();
	}).delegate("#jumpToStart", "click", function() {
		$("#desktop").animate({
			scrollTop: 0
		});
	}).delegate(".documentList circle, #groupG rect", "click", moveToTopic);

	self.minHeight = 400;
	self.minWidth = 800;

	$(window).resize(function() {
		ko.postbox.publish("windowWidth",Math.max(self.minWidth, $(window).width(), /* For opera: */ document.documentElement.clientWidth));
		ko.postbox.publish("windowHeight",Math.max(self.minHeight, $(window).height(), /* For opera: */ document.documentElement.clientHeight));
		setTopicSlider();
	});

	setTimeout(function() {
		ko.applyBindings(new App());
	}, 0);

	setTimeout(function() {
		ko.postbox.publish("windowWidth",Math.max(self.minWidth, $(window).width(), /* For opera: */ document.documentElement.clientWidth));
		ko.postbox.publish("windowHeight",Math.max(self.minHeight, $(window).height(), /* For opera: */ document.documentElement.clientHeight));
		setTopicSlider();
	}, 2500);

});

function setTopicSlider() {
	var slider = $('.topicPrevSlider');
	var maxListWidth = $('.topicList > ul').width();
	var topicDivWidth = $('.topicList').width();
	var bottomDivWidth = $('.topicBottomSliderDiv').width();

	slider.width((topicDivWidth*bottomDivWidth)/ maxListWidth);

	$('.topicPrevSlider > span').css('margin-left', (topicDivWidth * bottomDivWidth) / (maxListWidth * 2) - ($('.topicPrevSlider > span').width() / 2));
	var maxScrollPos = $('.topicBottomSliderDiv').width() - $('.topicPrevSlider').width();
	$( ".topicPrevSlider" ).draggable({
		axis: "x",
		containment: [ 0, 0, maxScrollPos, 0 ],
		drag: function( event, ui ) {
			var maxScroll = (maxListWidth - topicDivWidth);
			var scroll = ((ui.position.left + 4) / maxScrollPos) * maxScroll ;
			$('.topicList').scrollLeft(scroll);
			$('#topicMenu, .topicList > img').css('left', scroll);
		}
	});
};

function makeMenu(el) {
	$(el).menu({
		select : function(event, ui) {
			$(this).parent().parent().prev()
				.toggleClass("rotate1 rotate2");
			$(this).parent().parent().toggle('blind');
		}
	});
};

function getScrollPositionByValue(val) {
	var offset = 3;
	var scroll = val;
	var maxScrollPos = $('.topicBottomSliderDiv').width() - $('.topicPrevSlider').width();
	var maxScroll = $('.topicList > ul').width() - $('.topicList').width();
	var position = Math.round(scroll*maxScrollPos/maxScroll)+offset;
	if(position < 0)
		position = 0;
	if(position > maxScrollPos)
		position = maxScrollPos;
	return position;
};

function moveToTopic(self) {

	var topic_id = 0;
	if(!self.currentTarget) {
		topic_id = self;
	} else {
		topic_id = $(self.currentTarget).attr('id').split("_")[1];
	}
	var offset = $(".topicList").width() / 2 - $("#topic" + topic_id).width() / 2;

	$(".topicList").animate({
		scrollLeft : ($("#topic" + topic_id).position().left - offset)
	}, {
		duration : 2000,
		easing : "swing"
	});
	$(".topicPrevSlider").animate({
		left : getScrollPositionByValue(($("#topic" + topic_id).position().left - offset))
	}, {
		duration : 2000,
		easing : "swing"
	});
	setTimeout(function() {
		$(".topicList > img, #topicMenu").css('left', $(".topicList").scrollLeft());
	}, 2000);
};

<|endoftext|>


<commit_before>'use strict';

/**
 * @file
 * Configure and start our server
 */

// Config
import config from '@dbcdk/dbc-config';
// newrelic needs to be required the es5 way because we only wants to load new relic if specified in config.js
const newrelic = config.palle.newrelic && require('newrelic') || null;
import {version} from '../package.json';

// Libraries
import express from 'express';
import path from 'path';
import Logger from 'dbc-node-logger';
import RedisStore from 'connect-redis';
import ServiceProviderSetup from './ServiceProviderSetup.js';

// Routes
import MainRoutes from './server/routes/main.routes.js';

// Middleware
import mobilsoegmiddleware from './server/middlewares/mobilsoeg.middleware.js';
import bodyParser from 'body-parser';
import expressValidator from 'express-validator';
import compression from 'compression';
import expressSession from 'express-session';
import helmet from 'helmet';
import {GlobalsMiddleware} from './server/middlewares/globals.middleware';
import dbcMiddleware from './server/middlewares/middleware';

// Passport
import * as PassportStrategies from './server/PassportStrategies/strategies.passport';

// Generation of swagger specification
import swaggerFromSpec from './swaggerFromSpec.js';

module.exports.run = function (worker) {
  // Setup
  const app = express();
  const server = worker.httpServer;
  const scServer = worker.getSCServer();
  const ENV = app.get('env');
  const PRODUCTION = ENV === 'production';
  const APP_NAME = process.env.NEW_RELIC_APP_NAME || 'app_name'; // eslint-disable-line no-process-env
  const APPLICATION = 'mobilsoeg';
  const DEFAULT_CONFIG_NAME = 'aarhus'; // used as a fallback config, if none is set by a url.
  const logger = new Logger({app_name: APP_NAME});
  const expressLoggers = logger.getExpressLoggers();

  // Direct requests to app
  server.on('request', app);

  // Setting bodyparser
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({extended: true}));

  // Helmet configuration
  // TODO: Setup rest of Helmet, in a way that works with the server setup.
  app.use(helmet.frameguard());
  app.use(helmet.hidePoweredBy({setTo: 'Funkys Venner!'}));
  app.use(helmet.ieNoOpen());
  app.use(helmet.noSniff());

  // Port config
  app.set('port', process.env.PORT || 8080); // eslint-disable-line no-process-env

  // EMAIL Redirect requires port to be defined therefore it must come after
  const EMAIL_REDIRECT = process.env.EMAIL_REDIRECT || 'localhost:' + app.get('port'); // eslint-disable-line no-process-env

  // Configure app variables
  app.set('serviceProvider', ServiceProviderSetup(config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME], logger, worker)); // eslint-disable-line no-process-env
  app.set('logger', logger);
  app.set('EMAIL_REDIRECT', EMAIL_REDIRECT);
  app.set('APPLICATION', APPLICATION);
  app.set('Configuration', config);

  // Configure templating
  app.set('views', path.join(__dirname, 'server/templates'));
  app.set('view engine', 'jade');

  // Setting proxy
  app.enable('trust proxy');

  // settings production specific options
  if (!PRODUCTION && newrelic) {
    newrelic.agent_enabled = false;
  }

  // setting local vars that should be available to our template engine
  app.locals.newrelic = newrelic;
  app.locals.env = ENV;
  app.locals.version = version;
  app.locals.production = PRODUCTION;
  app.locals.title = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].applicationTitle || ''; // eslint-disable-line no-process-env
  app.locals.application = APPLICATION;
  app.locals.faviconUrl = APPLICATION === 'mobilsoeg' ? 'https://www.aakb.dk/sites/www.aakb.dk/files/favicon.ico' : '/favicon.ico';

  // Setup environments
  let redisConfig;
  let fileHeaders = {};

  // Redis
  switch (ENV) {
    case 'development':
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.development; // eslint-disable-line no-process-env
      break;
    case 'production':
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.production; // eslint-disable-line no-process-env
      fileHeaders = {index: false, dotfiles: 'ignore', maxAge: '5 days'};
      break;
    default:
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.local; // eslint-disable-line no-process-env
      break;
  }

  let redisStore = RedisStore(expressSession);

  let sessionMiddleware = expressSession({
    store: new redisStore({
      host: redisConfig.host,
      port: redisConfig.port,
      prefix: APP_NAME + '_session_'
    }),
    secret: redisConfig.secret + APP_NAME,
    name: APP_NAME,
    rolling: true,
    resave: false,
    saveUninitialized: false,
    cookie: {
      path: '/',
      httpOnly: true,
      secure: PRODUCTION
    }
  });

  // Adding gzip'ing
  app.use(compression());

  // Setting paths
  app.use(express.static(path.join(__dirname, '../public'), fileHeaders));
  app.use(express.static(path.join(__dirname, '../static'), fileHeaders));

  // Setting logger
  app.use(expressLoggers.logger);

  // Setting Input Validation
  const validatorOptions = {
    customValidators: {
      isEqual: (a, b) => {
        return a === b;
      }
    }
  };
  app.use(expressValidator(validatorOptions));

  // Setting sessions
  app.use(sessionMiddleware);

  scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, (req, next) => {
    sessionMiddleware(req.socket.request, {}, next);
  });

  // Detect library and set context
  app.use(mobilsoegmiddleware.libraryStyleWare);

  scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, (req, next) => {
    mobilsoegmiddleware.librarySocketWare(config, req.socket, next);
  });

  // Setup passport
  PassportStrategies.MobilSoegPassportConfig(app);

  // Setting middleware
  app.use('*', GlobalsMiddleware); // should be placed after PassportStrategies.MobilSoegPassportConfig

  // SSR middleware to add utility methods, and render footer automatically.
  app.use('*', dbcMiddleware.ssrMiddleware, dbcMiddleware.ssrFooter, dbcMiddleware.ssrHeader);

  // Setup Routes
  app.use('/', dbcMiddleware.cacheMiddleware, MainRoutes);

  // Actual used route
  app.use('/api', express.Router().all(['/:event'], (req, res) => {
    const event = req.params.event;
    if (event === 'swagger.json') {
      return swaggerFromSpec().then((response) => {
        res.json(response);
      }, (error) => {
        res.json(error);
      });
    }

    const query = req.body[0];

    // very long timeout
    let prom = res.callServiceProvider(event, query, 900000);
    prom = Array.isArray(prom) ? prom : [prom];
    Promise.all(prom).then((response) => {
      res.json(response);
    }, (error) => {
      res.json(error);
    });
  }));

  // Graceful handling of errors
  app.use((err, req, res, next) => {
    logger.log('error', 'An error occurred! Got following: ' + err);
    console.error('error', 'An error occurred! Got following: ', err); // eslint-disable-line no-console
    console.error(err.stack); // eslint-disable-line no-console
    if (res.headersSent) {
      return next(err);
    }

    res.status(500);
    res.json({error: String(err)});
    res.end();
  });

  // Handle 404's
  app.use((req, res) => {
    res.status(404);
    res.json({error: '404 Not Found'});
    res.end();
  });

  // Setting logger -- should be placed after routes
  app.use(expressLoggers.errorLogger);

  logger.log('debug', '>> Worker PID: ' + process.pid);
  logger.log('debug', 'Server listening on port ' + app.get('port'));
  logger.log('debug', 'NEW_RELIC_APP_NAME: ' + APP_NAME);
  logger.log('debug', 'APPLICATION: ' + APPLICATION);
  logger.log('debug', 'EMAIL_REDIRECT: ' + EMAIL_REDIRECT);
  logger.log('info', 'Versions: ', process.versions);
  logger.log('info', version + ' is up and running');
};
<commit_msg>first step towards not using serviceProvider through middleware<commit_after>'use strict';

/**
 * @file
 * Configure and start our server
 */

// Config
import config from '@dbcdk/dbc-config';
// newrelic needs to be required the es5 way because we only wants to load new relic if specified in config.js
const newrelic = config.palle.newrelic && require('newrelic') || null;
import {version} from '../package.json';

// Libraries
import express from 'express';
import path from 'path';
import Logger from 'dbc-node-logger';
import RedisStore from 'connect-redis';
import ServiceProviderSetup from './ServiceProviderSetup.js';

// Routes
import MainRoutes from './server/routes/main.routes.js';

// Middleware
import mobilsoegmiddleware from './server/middlewares/mobilsoeg.middleware.js';
import bodyParser from 'body-parser';
import expressValidator from 'express-validator';
import compression from 'compression';
import expressSession from 'express-session';
import helmet from 'helmet';
import {GlobalsMiddleware} from './server/middlewares/globals.middleware';
import dbcMiddleware from './server/middlewares/middleware';

// Passport
import * as PassportStrategies from './server/PassportStrategies/strategies.passport';

// Generation of swagger specification
import swaggerFromSpec from './swaggerFromSpec.js';

module.exports.run = function (worker) {
  // Setup
  const app = express();
  const server = worker.httpServer;
  const scServer = worker.getSCServer();
  const ENV = app.get('env');
  const PRODUCTION = ENV === 'production';
  const APP_NAME = process.env.NEW_RELIC_APP_NAME || 'app_name'; // eslint-disable-line no-process-env
  const APPLICATION = 'mobilsoeg';
  const DEFAULT_CONFIG_NAME = 'aarhus'; // used as a fallback config, if none is set by a url.
  const logger = new Logger({app_name: APP_NAME});
  const expressLoggers = logger.getExpressLoggers();

  // Direct requests to app
  server.on('request', app);

  // Setting bodyparser
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({extended: true}));

  // Helmet configuration
  // TODO: Setup rest of Helmet, in a way that works with the server setup.
  app.use(helmet.frameguard());
  app.use(helmet.hidePoweredBy({setTo: 'Funkys Venner!'}));
  app.use(helmet.ieNoOpen());
  app.use(helmet.noSniff());

  // Port config
  app.set('port', process.env.PORT || 8080); // eslint-disable-line no-process-env

  // EMAIL Redirect requires port to be defined therefore it must come after
  const EMAIL_REDIRECT = process.env.EMAIL_REDIRECT || 'localhost:' + app.get('port'); // eslint-disable-line no-process-env

  // Configure app variables
  let serviceProvider = ServiceProviderSetup(config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME], logger, worker); // eslint-disable-line no-process-env
  app.set('serviceProvider', serviceProvider);
  app.set('logger', logger);
  app.set('EMAIL_REDIRECT', EMAIL_REDIRECT);
  app.set('APPLICATION', APPLICATION);
  app.set('Configuration', config);

  // Configure templating
  app.set('views', path.join(__dirname, 'server/templates'));
  app.set('view engine', 'jade');

  // Setting proxy
  app.enable('trust proxy');

  // settings production specific options
  if (!PRODUCTION && newrelic) {
    newrelic.agent_enabled = false;
  }

  // setting local vars that should be available to our template engine
  app.locals.newrelic = newrelic;
  app.locals.env = ENV;
  app.locals.version = version;
  app.locals.production = PRODUCTION;
  app.locals.title = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].applicationTitle || ''; // eslint-disable-line no-process-env
  app.locals.application = APPLICATION;
  app.locals.faviconUrl = APPLICATION === 'mobilsoeg' ? 'https://www.aakb.dk/sites/www.aakb.dk/files/favicon.ico' : '/favicon.ico';

  // Setup environments
  let redisConfig;
  let fileHeaders = {};

  // Redis
  switch (ENV) {
    case 'development':
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.development; // eslint-disable-line no-process-env
      break;
    case 'production':
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.production; // eslint-disable-line no-process-env
      fileHeaders = {index: false, dotfiles: 'ignore', maxAge: '5 days'};
      break;
    default:
      redisConfig = config[process.env.CONFIG_NAME || DEFAULT_CONFIG_NAME].sessionStores.redis.local; // eslint-disable-line no-process-env
      break;
  }

  let redisStore = RedisStore(expressSession);

  let sessionMiddleware = expressSession({
    store: new redisStore({
      host: redisConfig.host,
      port: redisConfig.port,
      prefix: APP_NAME + '_session_'
    }),
    secret: redisConfig.secret + APP_NAME,
    name: APP_NAME,
    rolling: true,
    resave: false,
    saveUninitialized: false,
    cookie: {
      path: '/',
      httpOnly: true,
      secure: PRODUCTION
    }
  });

  // Adding gzip'ing
  app.use(compression());

  // Setting paths
  app.use(express.static(path.join(__dirname, '../public'), fileHeaders));
  app.use(express.static(path.join(__dirname, '../static'), fileHeaders));

  // Setting logger
  app.use(expressLoggers.logger);

  // Setting Input Validation
  const validatorOptions = {
    customValidators: {
      isEqual: (a, b) => {
        return a === b;
      }
    }
  };
  app.use(expressValidator(validatorOptions));

  // Setting sessions
  app.use(sessionMiddleware);

  scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, (req, next) => {
    sessionMiddleware(req.socket.request, {}, next);
  });

  // Detect library and set context
  app.use(mobilsoegmiddleware.libraryStyleWare);

  scServer.addMiddleware(scServer.MIDDLEWARE_EMIT, (req, next) => {
    mobilsoegmiddleware.librarySocketWare(config, req.socket, next);
  });

  // Setup passport
  PassportStrategies.MobilSoegPassportConfig(app);

  // Setting middleware
  app.use('*', GlobalsMiddleware); // should be placed after PassportStrategies.MobilSoegPassportConfig

  // SSR middleware to add utility methods, and render footer automatically.
  app.use('*', dbcMiddleware.ssrMiddleware, dbcMiddleware.ssrFooter, dbcMiddleware.ssrHeader);

  // Setup Routes
  app.use('/', dbcMiddleware.cacheMiddleware, MainRoutes);

  // Actual used route
  app.use('/api', express.Router().all(['/:event'], (req, res) => {
    const event = req.params.event;
    if (event === 'swagger.json') {
      return swaggerFromSpec().then((response) => {
        res.json(response);
      }, (error) => {
        res.json(error);
      });
    }

    const query = req.body[0];

    // TODO: currently context is connection-like object,
    // - should be refactored to be a simple transport-independent context.
    let connection = {
      request: { session: req.session },
      libdata: res.locals.libdata
    };
    let prom = serviceProvider.trigger(event, query, connection)

    // TODO: result from serviceProvider should just be a single promise.
    if(Array.isArray(prom)) {
      console.log('warning', 'result is array, instead of single promise', event); // eslint-disable-line no-console
      if(prom.length !== 1) {
        console.error('error', 'result length is ', prom.length); // eslint-disable-line no-console
      }
      prom = Array.isArray(prom) ? prom : [prom];
    }
    Promise.all(prom).then((response) => {
      res.json(response);
    }, (error) => {
      res.json(error);
    });
  }));

  // Graceful handling of errors
  app.use((err, req, res, next) => {
    logger.log('error', 'An error occurred! Got following: ' + err);
    console.error('error', 'An error occurred! Got following: ', err); // eslint-disable-line no-console
    console.error(err.stack); // eslint-disable-line no-console
    if (res.headersSent) {
      return next(err);
    }

    res.status(500);
    res.json({error: String(err)});
    res.end();
  });

  // Handle 404's
  app.use((req, res) => {
    res.status(404);
    res.json({error: '404 Not Found'});
    res.end();
  });

  // Setting logger -- should be placed after routes
  app.use(expressLoggers.errorLogger);

  logger.log('debug', '>> Worker PID: ' + process.pid);
  logger.log('debug', 'Server listening on port ' + app.get('port'));
  logger.log('debug', 'NEW_RELIC_APP_NAME: ' + APP_NAME);
  logger.log('debug', 'APPLICATION: ' + APPLICATION);
  logger.log('debug', 'EMAIL_REDIRECT: ' + EMAIL_REDIRECT);
  logger.log('info', 'Versions: ', process.versions);
  logger.log('info', version + ' is up and running');
};
<|endoftext|>


<commit_before>"use strict";

var app = angular.module('js110', []);

app.controller('controller', ['$scope', function($scope) {
  var audioContext;

  var synth = {
    instruments: [],
    tracks: [],
    transport: null,
  };

  $scope.playing = false;
  $scope.tempo = 100;
  $scope.loop = true;
  $scope.downloadFileName = "js-110";

  $scope.instruments = [{
                          waveform:           'sawtooth',
                          amplitude:          0.75,
                          lfoWaveform:        'sine',
                          lfoFrequency:       5,
                          lfoAmplitude:       0,
                          filterCutoff:       1000,
                          filterResonance:    0,
                          filterLFOWaveform:  'sine',
                          filterLFOFrequency: 5,
                          filterLFOAmplitude: 0,
                          envelopeAttack:     0.0,
                          envelopeDecay:      0.0,
                          envelopeSustain:    1.0,
                          envelopeRelease:    0.0,
                       },];

  $scope.tracks = [{
                     muted: false,
                     notes: [{name: 'C3'},
                             {name: ''},
                             {name: 'Eb3'},
                             {name: 'F3'},
                             {name: 'G3'},
                             {name: 'Bb4'},
                             {name: 'F3'},
                             {name: 'Bb4'},
                             {name: 'C3'},
                             {name: ''},
                             {name: 'Eb3'},
                             {name: 'F3'},
                             {name: 'D3'},
                             {name: 'Eb3'},
                             {name: 'D3'},
                             {name: 'Bb3'},],
                   },
                   {
                     muted: false,
                     notes: [{name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},],
                   },
                   {
                     muted: false,
                     notes: [{name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},],
                   },];

  var toGenericConfig = function() {
    var filterCutoff = parseInt($scope.instruments[0].filterCutoff, 10);

    return {
      waveform:  $scope.instruments[0].waveform,
      amplitude: parseFloat($scope.instruments[0].amplitude),
      lfo: {
        waveform:  $scope.instruments[0].lfoWaveform,
        frequency: parseFloat($scope.instruments[0].lfoFrequency),
        amplitude: parseInt($scope.instruments[0].lfoAmplitude, 10),
      },
      filter: {
        cutoff:    filterCutoff,
        resonance: parseInt($scope.instruments[0].filterResonance, 10),
        lfo: {
          waveform:  $scope.instruments[0].filterLFOWaveform,
          frequency: parseFloat($scope.instruments[0].filterLFOFrequency),
          amplitude: parseFloat($scope.instruments[0].filterLFOAmplitude) * filterCutoff,
        },
      },
      envelope: {
        attack:  parseFloat($scope.instruments[0].envelopeAttack),
        decay:   parseFloat($scope.instruments[0].envelopeDecay),
        sustain: parseFloat($scope.instruments[0].envelopeSustain),
        release: parseFloat($scope.instruments[0].envelopeRelease),
      },
    };
  };

  var parseNotes = function() {
    var result = [];

    for (var t = 0; t < $scope.tracks.length; t++) {
      var rawNotes = [];
      for (var n = 0; n < $scope.tracks[t].notes.length; n++) {
        rawNotes[n] = $scope.tracks[t].notes[n].name;
      }

      result.push(rawNotes.join(' '));
    }

    return result;
  };

  var stopCallback = function() {
    $scope.playing = false;
    $scope.$digest();
  };

  $scope.init = function() {
    if (window.AudioContext) {
      audioContext = new AudioContext();

      var config = toGenericConfig();
      var instrument = new JSSynth.Instrument(audioContext, config);

      synth.instruments = [instrument];

      var parsedTracks = parseNotes();
      for (var i = 0; i < parsedTracks.length; i++) {
        var sequence = JSSynth.SequenceParser.parse(parsedTracks[i]);
        synth.tracks.push(new JSSynth.Track(instrument, sequence, $scope.tracks[i].muted));
      }

      synth.transport = new JSSynth.Transport(audioContext, synth.tracks, stopCallback);
      synth.transport.setTempo(parseInt($scope.tempo, 10));
    }
    else {
      alert("Your browser doesn't appear to support WebAudio, and so won't be able to use the JS-110. Try a recent version of Chrome, Safari, or Firefox.");
      return;
    }
  };
  $scope.init();

  $scope.updateInstrument = function() {
    var config = toGenericConfig();
    synth.instruments[0] = new JSSynth.Instrument(audioContext, config);
    var i;

    for (i = 0; i < synth.tracks.length; i++) {
      synth.tracks[i].instrument = synth.instruments[0];
    }
  };

  $scope.updateNotes = function() {
    // Should see how to update just the relevant track/note, rather than all tracks/notes
    var i;
    var parsedNotes = parseNotes();
    for (i = 0; i < parsedNotes.length; i++) {
      synth.tracks[i].setNotes(parsedNotes[i]);
    }
  };

  $scope.addTrack = function() {
    $scope.tracks.push({
                         muted: false,
                         notes: [{name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''}],
                       });

    var parsedTracks = parseNotes();
    var sequence = JSSynth.SequenceParser.parse(parsedTracks[parsedTracks.length - 1]);
    synth.tracks.push(new JSSynth.Track(synth.instruments[0], sequence, $scope.tracks[$scope.tracks.length - 1].muted));
  };

  $scope.removeTrack = function(index) {
    $scope.tracks.splice(index, 1);
    synth.tracks.splice(index, 1);
  };

  $scope.updateTempo = function() {
    synth.transport.setTempo(parseInt($scope.tempo, 10));
  };

  $scope.updateLoop = function() {
    synth.transport.loop = $scope.loop;
  };

  $scope.toggleTrackMute = function(index) {
    $scope.tracks[index].muted = !$scope.tracks[index].muted;
    synth.tracks[index].setIsMuted($scope.tracks[index].muted);
  };

  $scope.toggle = function() {
    synth.transport.toggle();
    $scope.playing = !$scope.playing;
  };

  $scope.export = function() {
    var offlineAudioContext = new webkitOfflineAudioContext(1, 44100 * 4, 44100);

    var instrument = new JSSynth.Instrument(offlineAudioContext, toGenericConfig());

    var tracks = [];
    var parsedTracks = parseNotes();
    for (var i = 0; i < parsedTracks.length; i++) {
      var sequence = JSSynth.SequenceParser.parse(parsedTracks[i]);
      tracks.push(new JSSynth.Track(instrument, sequence, $scope.tracks[i].muted));
    }

    var offlineTransport = new JSSynth.OfflineTransport(offlineAudioContext, tracks, $scope.downloadFileName, function() { });
    offlineTransport.setTempo(parseInt($scope.tempo, 10));
    offlineTransport.tick();
  };
}]);

app.directive('noteInput', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ctrl) {
       if (!ctrl) return;

       var formatNoteValue = function(rawValue) {
         var formattedValue = rawValue;

         // Make first character uppercase (but not subsequent characters, to avoid
         // making a 'b' uppercase, which will mess with ♭ replacement).
         var firstCharacter = formattedValue.substr(0, 1);
         formattedValue = firstCharacter.toUpperCase() + formattedValue.substr(1);

         formattedValue = formattedValue.replace("##", "𝄪");
         formattedValue = formattedValue.replace("#", "♯");
         formattedValue = formattedValue.replace("bb", "𝄫");
         formattedValue = formattedValue.replace("b", "♭");
         formattedValue = formattedValue.replace("-", "—");

         return formattedValue;
       };

       ctrl.$formatters.push(function (a) {
         return formatNoteValue(ctrl.$modelValue);
       });

       ctrl.$parsers.unshift(function (viewValue) {
         var parsedValue = viewValue;

         // Make first character uppercase (but not subsequent characters, to avoid
         // making a 'b' uppercase, which will mess with ♭ replacement).
         var firstCharacter = viewValue.substr(0, 1);
         parsedValue = firstCharacter.toUpperCase() + viewValue.substr(1);
         parsedValue = parsedValue.replace("♯", "#");
         parsedValue = parsedValue.replace("𝄪", "##");
         parsedValue = parsedValue.replace("♭", "b");
         parsedValue = parsedValue.replace("𝄫", "bb");

         if (/^$|^-$|(^[A-G](b|bb|#|##){0,1}[0-7]$)/.test(parsedValue)) {
           ctrl.$setValidity('noteInput', true);
           return parsedValue;
         }
         else {
           ctrl.$setValidity('noteInput', false);
           return '';
         }
       });

       element.bind('blur', function(e) {
         element.val(formatNoteValue(element.val()));
       });

       element.bind('keydown', function(e) {
         var changeCurrentlySelectedNote = function(element, config) {
           var trackIndex = parseInt(element[0].id.split("-")[1], 10);
           var noteIndex = parseInt(element[0].id.split("-")[3], 10);
           var nextNoteId = 'track-' + (trackIndex + config.trackIndexDelta) + '-note-' + (noteIndex + config.noteIndexDelta);

           document.getElementById(nextNoteId).focus();
         };

         if (e.keyCode === 32) {  // Space bar
           element.val('');
         }
         else if (e.keyCode === 37) {  // Left arrow key
           if (element[0].selectionStart === 0 && !(element.hasClass('firstNote'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 0, noteIndexDelta: -1 });
           }
         }
         else if (e.keyCode === 39) {  // Right arrow key
           if (element[0].selectionEnd === element.val().length && !(element.hasClass('lastNote'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 0, noteIndexDelta: 1 });
           }
         }
         else if (e.keyCode === 38) {  // Up arrow key
           if (!(element.hasClass('firstTrack'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: -1, noteIndexDelta: 0 });
           }
         }
         else if (e.keyCode === 40) {  // Down arrow key
           if (!(element.hasClass('lastTrack'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 1, noteIndexDelta: 0 });
           }
         }
       });

       element.bind('keyup', function(e) {
         if (e.keyCode === 32) {  // Space bar
           element.val('');
         }
       });
    }
  };
});
<commit_msg>Using forEach<commit_after>"use strict";

var app = angular.module('js110', []);

app.controller('controller', ['$scope', function($scope) {
  var audioContext;

  var synth = {
    instruments: [],
    tracks: [],
    transport: null,
  };

  $scope.playing = false;
  $scope.tempo = 100;
  $scope.loop = true;
  $scope.downloadFileName = "js-110";

  $scope.instruments = [{
                          waveform:           'sawtooth',
                          amplitude:          0.75,
                          lfoWaveform:        'sine',
                          lfoFrequency:       5,
                          lfoAmplitude:       0,
                          filterCutoff:       1000,
                          filterResonance:    0,
                          filterLFOWaveform:  'sine',
                          filterLFOFrequency: 5,
                          filterLFOAmplitude: 0,
                          envelopeAttack:     0.0,
                          envelopeDecay:      0.0,
                          envelopeSustain:    1.0,
                          envelopeRelease:    0.0,
                       },];

  $scope.tracks = [{
                     muted: false,
                     notes: [{name: 'C3'},
                             {name: ''},
                             {name: 'Eb3'},
                             {name: 'F3'},
                             {name: 'G3'},
                             {name: 'Bb4'},
                             {name: 'F3'},
                             {name: 'Bb4'},
                             {name: 'C3'},
                             {name: ''},
                             {name: 'Eb3'},
                             {name: 'F3'},
                             {name: 'D3'},
                             {name: 'Eb3'},
                             {name: 'D3'},
                             {name: 'Bb3'},],
                   },
                   {
                     muted: false,
                     notes: [{name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},
                             {name: 'C2'},
                             {name: ''},],
                   },
                   {
                     muted: false,
                     notes: [{name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},
                             {name: 'Eb3'},
                             {name: '-'},
                             {name: '-'},
                             {name: '-'},],
                   },];

  var toGenericConfig = function() {
    var filterCutoff = parseInt($scope.instruments[0].filterCutoff, 10);

    return {
      waveform:  $scope.instruments[0].waveform,
      amplitude: parseFloat($scope.instruments[0].amplitude),
      lfo: {
        waveform:  $scope.instruments[0].lfoWaveform,
        frequency: parseFloat($scope.instruments[0].lfoFrequency),
        amplitude: parseInt($scope.instruments[0].lfoAmplitude, 10),
      },
      filter: {
        cutoff:    filterCutoff,
        resonance: parseInt($scope.instruments[0].filterResonance, 10),
        lfo: {
          waveform:  $scope.instruments[0].filterLFOWaveform,
          frequency: parseFloat($scope.instruments[0].filterLFOFrequency),
          amplitude: parseFloat($scope.instruments[0].filterLFOAmplitude) * filterCutoff,
        },
      },
      envelope: {
        attack:  parseFloat($scope.instruments[0].envelopeAttack),
        decay:   parseFloat($scope.instruments[0].envelopeDecay),
        sustain: parseFloat($scope.instruments[0].envelopeSustain),
        release: parseFloat($scope.instruments[0].envelopeRelease),
      },
    };
  };

  var parseNotes = function() {
    var result = [];
    var rawNotes;

    $scope.tracks.forEach(function(track) {
      rawNotes = [];

      track.notes.forEach(function(note, index) {
        rawNotes[index] = note.name;
      });

      result.push(rawNotes.join(' '));
    });

    return result;
  };

  var stopCallback = function() {
    $scope.playing = false;
    $scope.$digest();
  };

  $scope.init = function() {
    if (window.AudioContext) {
      audioContext = new AudioContext();

      var config = toGenericConfig();
      var instrument = new JSSynth.Instrument(audioContext, config);

      synth.instruments = [instrument];

      var parsedTracks = parseNotes();
      for (var i = 0; i < parsedTracks.length; i++) {
        var sequence = JSSynth.SequenceParser.parse(parsedTracks[i]);
        synth.tracks.push(new JSSynth.Track(instrument, sequence, $scope.tracks[i].muted));
      }

      synth.transport = new JSSynth.Transport(audioContext, synth.tracks, stopCallback);
      synth.transport.setTempo(parseInt($scope.tempo, 10));
    }
    else {
      alert("Your browser doesn't appear to support WebAudio, and so won't be able to use the JS-110. Try a recent version of Chrome, Safari, or Firefox.");
      return;
    }
  };
  $scope.init();

  $scope.updateInstrument = function() {
    var config = toGenericConfig();
    synth.instruments[0] = new JSSynth.Instrument(audioContext, config);

    synth.tracks.forEach(function(track) {
      track.instrument = synth.instruments[0];
    });
  };

  $scope.updateNotes = function() {
    // Should see how to update just the relevant track/note, rather than all tracks/notes
    var i;
    var parsedNotes = parseNotes();
    for (i = 0; i < parsedNotes.length; i++) {
      synth.tracks[i].setNotes(parsedNotes[i]);
    }
  };

  $scope.addTrack = function() {
    $scope.tracks.push({
                         muted: false,
                         notes: [{name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''},
                                 {name: ''}],
                       });

    var parsedTracks = parseNotes();
    var sequence = JSSynth.SequenceParser.parse(parsedTracks[parsedTracks.length - 1]);
    synth.tracks.push(new JSSynth.Track(synth.instruments[0], sequence, $scope.tracks[$scope.tracks.length - 1].muted));
  };

  $scope.removeTrack = function(index) {
    $scope.tracks.splice(index, 1);
    synth.tracks.splice(index, 1);
  };

  $scope.updateTempo = function() {
    synth.transport.setTempo(parseInt($scope.tempo, 10));
  };

  $scope.updateLoop = function() {
    synth.transport.loop = $scope.loop;
  };

  $scope.toggleTrackMute = function(index) {
    $scope.tracks[index].muted = !$scope.tracks[index].muted;
    synth.tracks[index].setIsMuted($scope.tracks[index].muted);
  };

  $scope.toggle = function() {
    synth.transport.toggle();
    $scope.playing = !$scope.playing;
  };

  $scope.export = function() {
    var offlineAudioContext = new webkitOfflineAudioContext(1, 44100 * 4, 44100);

    var instrument = new JSSynth.Instrument(offlineAudioContext, toGenericConfig());

    var tracks = [];
    var parsedTracks = parseNotes();
    for (var i = 0; i < parsedTracks.length; i++) {
      var sequence = JSSynth.SequenceParser.parse(parsedTracks[i]);
      tracks.push(new JSSynth.Track(instrument, sequence, $scope.tracks[i].muted));
    }

    var offlineTransport = new JSSynth.OfflineTransport(offlineAudioContext, tracks, $scope.downloadFileName, function() { });
    offlineTransport.setTempo(parseInt($scope.tempo, 10));
    offlineTransport.tick();
  };
}]);

app.directive('noteInput', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ctrl) {
       if (!ctrl) return;

       var formatNoteValue = function(rawValue) {
         var formattedValue = rawValue;

         // Make first character uppercase (but not subsequent characters, to avoid
         // making a 'b' uppercase, which will mess with ♭ replacement).
         var firstCharacter = formattedValue.substr(0, 1);
         formattedValue = firstCharacter.toUpperCase() + formattedValue.substr(1);

         formattedValue = formattedValue.replace("##", "𝄪");
         formattedValue = formattedValue.replace("#", "♯");
         formattedValue = formattedValue.replace("bb", "𝄫");
         formattedValue = formattedValue.replace("b", "♭");
         formattedValue = formattedValue.replace("-", "—");

         return formattedValue;
       };

       ctrl.$formatters.push(function (a) {
         return formatNoteValue(ctrl.$modelValue);
       });

       ctrl.$parsers.unshift(function (viewValue) {
         var parsedValue = viewValue;

         // Make first character uppercase (but not subsequent characters, to avoid
         // making a 'b' uppercase, which will mess with ♭ replacement).
         var firstCharacter = viewValue.substr(0, 1);
         parsedValue = firstCharacter.toUpperCase() + viewValue.substr(1);
         parsedValue = parsedValue.replace("♯", "#");
         parsedValue = parsedValue.replace("𝄪", "##");
         parsedValue = parsedValue.replace("♭", "b");
         parsedValue = parsedValue.replace("𝄫", "bb");

         if (/^$|^-$|(^[A-G](b|bb|#|##){0,1}[0-7]$)/.test(parsedValue)) {
           ctrl.$setValidity('noteInput', true);
           return parsedValue;
         }
         else {
           ctrl.$setValidity('noteInput', false);
           return '';
         }
       });

       element.bind('blur', function(e) {
         element.val(formatNoteValue(element.val()));
       });

       element.bind('keydown', function(e) {
         var changeCurrentlySelectedNote = function(element, config) {
           var trackIndex = parseInt(element[0].id.split("-")[1], 10);
           var noteIndex = parseInt(element[0].id.split("-")[3], 10);
           var nextNoteId = 'track-' + (trackIndex + config.trackIndexDelta) + '-note-' + (noteIndex + config.noteIndexDelta);

           document.getElementById(nextNoteId).focus();
         };

         if (e.keyCode === 32) {  // Space bar
           element.val('');
         }
         else if (e.keyCode === 37) {  // Left arrow key
           if (element[0].selectionStart === 0 && !(element.hasClass('firstNote'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 0, noteIndexDelta: -1 });
           }
         }
         else if (e.keyCode === 39) {  // Right arrow key
           if (element[0].selectionEnd === element.val().length && !(element.hasClass('lastNote'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 0, noteIndexDelta: 1 });
           }
         }
         else if (e.keyCode === 38) {  // Up arrow key
           if (!(element.hasClass('firstTrack'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: -1, noteIndexDelta: 0 });
           }
         }
         else if (e.keyCode === 40) {  // Down arrow key
           if (!(element.hasClass('lastTrack'))) {
             changeCurrentlySelectedNote(element, { trackIndexDelta: 1, noteIndexDelta: 0 });
           }
         }
       });

       element.bind('keyup', function(e) {
         if (e.keyCode === 32) {  // Space bar
           element.val('');
         }
       });
    }
  };
});
<|endoftext|>


<commit_before>jQuery(document).ready(function() {
		jQuery('#export_csv,.sk-fading-circle').hide();
		jQuery('#generate_csv').click(function (e) {
			var feed_url  = jQuery("#rss_url").val();
			if (feed_url.length == 0) {
				return alert('Input RSS url');
			}
			jQuery.ajax({
				url      : 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent(feed_url),
				dataType : 'json',
				success  : function (data) {
					if (data.responseData.feed && data.responseData.feed.entries) {
							 	var array_content = [];
								jQuery.each(data.responseData.feed.entries, function (index, data_set) {
									var array_data = [];
									var array_title = [];
									jQuery.each(data_set,function (index_key, data_output) {
										if (index == 0) {
											array_title.push(index_key);
										}
										data_output = data_output.toString();
										data_output = data_output.replace(/<(?:.|\n)*?>/gm,'');
										data_output = data_output.replace(/(\r\n|\n|\r|,)/gm,'');
										array_data.push(data_output);
									});
									if (index == 0) {
										array_content.push(array_title);
									}
									array_content.push(array_data);
								});
								// console.log(array_content);
								// Pattern Full Data
								var full_data_csv = "data:text/csv;charset=utf-8,";
								array_content.forEach(function(infoArray, index){
										 dataString = infoArray.join(",");
										 if (index < array_content.length) {
											full_data_csv += dataString+ "\n";
										 } else{
											full_data_csv += dataString;
										 }
								});
								var export_full_data_csv = encodeURI(full_data_csv);
								jQuery('#export_full_data_csv').attr('href',export_full_data_csv);
								// Pattern Full Detail
								var full_detail_csv = "data:text/csv;charset=utf-8,";
								array_content.forEach(function(infoArray, index){
									if (index != 0) {
										var url_data = infoArray[1];
										jQuery.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent(url_data) + '&callback=?', function(data){
											var data_set  = jQuery.parseHTML(data.contents);
											var wrapper_data = jQuery(data_set[49]);
											var text_data = wrapper_data.find('.post-wrap').text();
											var parent_set = jQuery('#list_full_detail_csv tbody');
											var html_pattern = '';
													html_pattern += '
';
													html_pattern += '';
													html_pattern += ''+url_data+'';
													html_pattern += '	';
													html_pattern += '';
													html_pattern += text_data;
													html_pattern += '	';
													html_pattern += '
';
											parent_set.append(html_pattern);
											var data_text_output = text_data;
											data_text_output = data_text_output.replace(/<(?:.|\n)*?>/gm,'');
											data_text_output = data_text_output.replace(/(\r\n|\n|\r|,)/gm,'');
											full_detail_csv += url_data+','+data_text_output+'\n';
											var export_full_detail_csv = encodeURI(full_detail_csv);
											jQuery('#export_full_detail_csv').attr('href',export_full_detail_csv);
										});
									}
								});
								// Display btn for export
								jQuery('#generate_csv').hide();
								jQuery('.sk-fading-circle').show('slow',function() {
									jQuery('#export_csv').delay(2000).show('slow',function() {
										jQuery('.sk-fading-circle').hide('fast');
									});
								});
					}
				}
			});
		});
});<commit_msg>update condition<commit_after>jQuery(document).ready(function() {
		jQuery('#export_csv,.sk-fading-circle').hide();
		jQuery('#generate_csv').click(function (e) {
			var feed_url  = jQuery("#rss_url").val();
			if (feed_url.length == 0) {
				return alert('Input RSS url');
			}
			jQuery.ajax({
				url      : 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=10&callback=?&q=' + encodeURIComponent(feed_url),
				dataType : 'json',
				success  : function (data) {
					if (data.responseData.feed && data.responseData.feed.entries) {
							 	var array_content = [];
								jQuery.each(data.responseData.feed.entries, function (index, data_set) {
									var array_data = [];
									var array_title = [];
									jQuery.each(data_set,function (index_key, data_output) {
										if (index == 0) {
											array_title.push(index_key);
										}
										data_output = data_output.toString();
										data_output = data_output.replace(/<(?:.|\n)*?>/gm,'');
										data_output = data_output.replace(/(\r\n|\n|\r|,)/gm,'');
										array_data.push(data_output);
									});
									if (index == 0) {
										array_content.push(array_title);
									}
									array_content.push(array_data);
								});
								// console.log(array_content);
								// Pattern Full Data
								var full_data_csv = "data:text/csv;charset=utf-8,";
								array_content.forEach(function(infoArray, index){
										 dataString = infoArray.join(",");
										 if (index < array_content.length) {
											full_data_csv += dataString+ "\n";
										 } else{
											full_data_csv += dataString;
										 }
								});
								var export_full_data_csv = encodeURI(full_data_csv);
								jQuery('#export_full_data_csv').attr('href',export_full_data_csv);
								// Pattern Full Detail
								var full_detail_csv = "data:text/csv;charset=utf-8,";
								array_content.forEach(function(infoArray, index){
									if (index != 0) {
										var url_data = infoArray[1];
										jQuery.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent(url_data) + '&callback=?', function(data){
											var data_set  = jQuery.parseHTML(data.contents);
											var visual_dom = jQuery('<output>').append(data_set);
											var wrapper_data = jQuery('#wrapper',visual_dom);
											var text_data = wrapper_data.find('.post-wrap').text();
											var parent_set = jQuery('#list_full_detail_csv tbody');
											var html_pattern = '';
													html_pattern += '
';
													html_pattern += '';
													html_pattern += ''+url_data+'';
													html_pattern += '	';
													html_pattern += '';
													html_pattern += text_data;
													html_pattern += '	';
													html_pattern += '
';
											parent_set.append(html_pattern);
											var data_text_output = text_data;
											data_text_output = data_text_output.replace(/<(?:.|\n)*?>/gm,'');
											data_text_output = data_text_output.replace(/(\r\n|\n|\r|,)/gm,'');
											full_detail_csv += url_data+','+data_text_output+'\n';
											var export_full_detail_csv = encodeURI(full_detail_csv);
											jQuery('#export_full_detail_csv').attr('href',export_full_detail_csv);
										});
									}
								});
								// Display btn for export
								jQuery('#generate_csv').hide();
								jQuery('.sk-fading-circle').show('slow',function() {
									jQuery('#export_csv').delay(2000).show('slow',function() {
										jQuery('.sk-fading-circle').hide('fast');
									});
								});
					}
				}
			});
		});
});<|endoftext|>


<commit_before>module.exports = function (grunt) {

    require('load-grunt-tasks')(grunt);

    grunt.initConfig({

        handlebars: {

            compile: {

                options: {
                    amd: ['handlebars', 'handlebars.helpers'],
                    namespace: 'templates',
                    processName: function (path) {
                        return path.match(/([\w]+)\.hbs/)[1];
                    }
                },

                files: {
                    'static/templates/compiled.js': ['src/views/**/*.hbs']
                }

            }

        },

        jasmine: {
            test: {
                options: {
                    specs: 'tests/*.js'
                }
            }
        },

        jshint: {

            server: {
                options: {
                    jshintrc: true
                },
                src: ['src/**/*.js']
            },

            client: {
                options: {
                    jshintrc: true
                },
                src: ['static/js/**/*.js']
            }

        },

        sass: {

            dist: {

                files: {
                    'static/css/styles.css': 'static/css/styles.scss'
                }

            }

        },

        watch: {

            handlebars: {
                files: ['src/views/**/*.hbs'],
                tasks: ['handlebars']
            },

            jshint: {
                files: ['src/**/*.js', 'static/js/**/*.js'],
                tasks: ['jshint']
            },

            sass: {
                files: ['static/css/**/*.scss'],
                tasks: ['sass']
            }

        }

    });

    grunt.registerTask('default', [ 'handlebars', 'jshint', 'sass' ]);
    grunt.registerTask('test', [ 'jasmine' ]);

};
<commit_msg>Added Handlebars partials support to Gruntfile.<commit_after>module.exports = function (grunt) {

    require('load-grunt-tasks')(grunt);

    grunt.initConfig({

        handlebars: {

            compile: {

                options: {
                    amd: ['handlebars', 'handlebars.helpers'],
                    namespace: 'templates',
                    partialRegex: /.*/,
                    partialsPathRegex: /\/partials\//,
                    processName: function (path) {
                        return path.match(/([\w]+)\.hbs/)[1];
                    }
                },

                files: {
                    'static/templates/compiled.js': ['src/views/**/*.hbs']
                }

            }

        },

        jasmine: {
            test: {
                options: {
                    specs: 'tests/*.js'
                }
            }
        },

        jshint: {

            server: {
                options: {
                    jshintrc: true
                },
                src: ['src/**/*.js']
            },

            client: {
                options: {
                    jshintrc: true
                },
                src: ['static/js/**/*.js']
            }

        },

        sass: {

            dist: {

                files: {
                    'static/css/styles.css': 'static/css/styles.scss'
                }

            }

        },

        watch: {

            handlebars: {
                files: ['src/views/**/*.hbs'],
                tasks: ['handlebars']
            },

            jshint: {
                files: ['src/**/*.js', 'static/js/**/*.js'],
                tasks: ['jshint']
            },

            sass: {
                files: ['static/css/**/*.scss'],
                tasks: ['sass']
            }

        }

    });

    grunt.registerTask('default', [ 'handlebars', 'jshint', 'sass' ]);
    grunt.registerTask('test', [ 'jasmine' ]);

};
<|endoftext|>


<commit_before>var fs = require("fs");
var https = require("https");
var path = require("path");
var spawn = require('child_process').spawn;
var url = require("url");

var ProgressBar = require('progress');

var updater = require("../lib/updater.js");
var files = require("../lib/files.js");

updater.get_manifest(function (manifest) {
  if (!manifest) {
    console.log("Failed to download manifest.");
    return;
  }

  if (!updater.needs_upgrade(manifest)) {
    if (manifest.version === updater.CURRENT_VERSION) {
      console.log("Already at current version: " + manifest.version);
    } else {
      console.log("Not upgrading. Your version: " + updater.CURRENT_VERSION
                  + ". New version: " + manifest.version + ".");
    }
    return;
  }

  console.log("New version available: " + manifest.version);
  var download_url = url.parse(manifest.url);
  // XXX why is node's API for url different from http?
  download_url.path = download_url.pathname;

  var req = https.request(download_url, function(res) {
    if (res.statusCode !== 200) {
      console.log("Failed to download: " + manifest.url);
      return;
    }
    var len = parseInt(res.headers['content-length'], 10);

    var bar = new ProgressBar('  downloading [:bar] :percent', {
      complete: '='
      , incomplete: ' '
      , width: 30
      , total: len
    });

    // find / make directory paths
    var base_dir = path.join(__dirname, "../../");
    var tmp_dir = path.join(base_dir, "tmp");
    try { fs.mkdirSync(tmp_dir, 0755); } catch (err) { }

    // open pipe to tar
    // XXX not always /usr/bin/tar !!!. linux is /bin/tar.
    var tar_proc = spawn("/usr/bin/tar", ["-C", tmp_dir, "-xzf", "-"]);

    // XXX
    tar_proc.stderr.setEncoding('utf8');
    tar_proc.stderr.on('data', function (data) {
      console.log(data);
    });

    res.on('data', function (chunk) {
      tar_proc.stdin.write(chunk);
      bar.tick(chunk.length);
    });
    res.on('end', function () {
      console.log("... finished download");
      tar_proc.stdin.end();
      tar_proc.on('exit', function (code, signal) {
        if (code !== 0 || signal) {
          console.log("failed to untar download");
          return;
        }

        // untar complete. swap directories
        var old_base_dir = base_dir.slice(0,-1) + ".old";
        if (path.existsSync(old_base_dir))
          files.rm_recursive(old_base_dir); // rm -rf !!

        fs.renameSync(base_dir, old_base_dir);
        fs.renameSync(old_base_dir + "/tmp/skybreak", base_dir);

        console.log("Upgrade complete.");
      });
    });

  });
  req.end();

});
<commit_msg>no reason to pass full pathname for tar here<commit_after>var fs = require("fs");
var https = require("https");
var path = require("path");
var spawn = require('child_process').spawn;
var url = require("url");

var ProgressBar = require('progress');

var updater = require("../lib/updater.js");
var files = require("../lib/files.js");

updater.get_manifest(function (manifest) {
  if (!manifest) {
    console.log("Failed to download manifest.");
    return;
  }

  if (!updater.needs_upgrade(manifest)) {
    if (manifest.version === updater.CURRENT_VERSION) {
      console.log("Already at current version: " + manifest.version);
    } else {
      console.log("Not upgrading. Your version: " + updater.CURRENT_VERSION
                  + ". New version: " + manifest.version + ".");
    }
    return;
  }

  console.log("New version available: " + manifest.version);
  var download_url = url.parse(manifest.url);
  // XXX why is node's API for url different from http?
  download_url.path = download_url.pathname;

  var req = https.request(download_url, function(res) {
    if (res.statusCode !== 200) {
      console.log("Failed to download: " + manifest.url);
      return;
    }
    var len = parseInt(res.headers['content-length'], 10);

    var bar = new ProgressBar('  downloading [:bar] :percent', {
      complete: '='
      , incomplete: ' '
      , width: 30
      , total: len
    });

    // find / make directory paths
    var base_dir = path.join(__dirname, "../../");
    var tmp_dir = path.join(base_dir, "tmp");
    try { fs.mkdirSync(tmp_dir, 0755); } catch (err) { }

    // open pipe to tar
    var tar_proc = spawn("tar", ["-C", tmp_dir, "-xzf", "-"]);

    // XXX
    tar_proc.stderr.setEncoding('utf8');
    tar_proc.stderr.on('data', function (data) {
      console.log(data);
    });

    res.on('data', function (chunk) {
      tar_proc.stdin.write(chunk);
      bar.tick(chunk.length);
    });
    res.on('end', function () {
      console.log("... finished download");
      tar_proc.stdin.end();
      tar_proc.on('exit', function (code, signal) {
        if (code !== 0 || signal) {
          console.log("failed to untar download");
          return;
        }

        // untar complete. swap directories
        var old_base_dir = base_dir.slice(0,-1) + ".old";
        if (path.existsSync(old_base_dir))
          files.rm_recursive(old_base_dir); // rm -rf !!

        fs.renameSync(base_dir, old_base_dir);
        fs.renameSync(old_base_dir + "/tmp/skybreak", base_dir);

        console.log("Upgrade complete.");
      });
    });

  });
  req.end();

});
<|endoftext|>


<commit_before>vinisketch.directive ('vsSplitView', function() {

  function setOrientation (scope, element, newOrient, currentOrient) {

    element.removeClass ('horizontal');
    element.removeClass ('vertical');

    switch (newOrient) {
      case undefined:
      case null:
      case "":
        scope.orientation = "horizontal";
        return;
      case "horizontal":
      case "vertical":
        break;
      default:
        console.warn ("Unsuported SplitView.orientation: " + newOrient);
        return;
    }

    element.addClass (newOrient);
  }

  function setMode (scope, element, newMode, currentMode) {

    element.removeClass ('tablet');
    element.removeClass ('phone');

    switch (newMode) {
      case undefined:
      case null:
      case "":
        scope.mode = "tablet";
        return;
      case "tablet":
      case "phone":
        break;
      default:
        console.warn ("Unsuported SplitView.mode: " + newMode);
        return;
    }

    element.addClass (newMode);
  }

  return {
    restrict: 'E',

    transclude: true,

    scope: {
      mode: "@",
      orientation: "@"
    },

    controller: function ($scope) {
      $scope.mode = "tablet";
      $scope.orientation = "vertical";
    },

    link: function (scope, element, attrs, controller, transclude) {

      element.addClass ("vs_ui_splitview");
      setMode (scope, element, scope.mode);
      setOrientation (scope, element, scope.orientation);

      var view_node = element[0];
      var main_panel_node;
      var secondary_panel_node;

      transclude (scope, function (cloned) {

        for (var i = 0, l = cloned.length; i < l; i++) {
          var item = cloned [i];
          if (item.tagName == 'VS-MAIN-PANEL') {
            main_panel_node = item;
            item.classList.add ("main_panel");
          }
          else if (item.tagName == 'VS-SECONDARY-PANEL') {
            secondary_panel_node = item;
            item.classList.add ("secondary_panel");
          }
        }
        view_node.appendChild (secondary_panel_node);
        view_node.appendChild (main_panel_node);
      });

      scope.$watch ('orientation', function (newOrientation, currentOrientation) {
        if (angular.isUndefined (newOrientation)) {
          return;
        }
        setOrientation (scope, element, newOrientation, currentOrientation);
      });

      scope.$watch ('mode', function (newMode, currentMode) {
        if (angular.isUndefined (newMode)) {
          return;
        }
        setMode (scope, element, newMode, currentMode);
      });

      element.on ('$destroy', function() {
        console.log ("vsButton $destroy");
      });
    }
  };
});<commit_msg>SplitView simplification with better use of ng-transclude directive<commit_after>vinisketch.directive ('vsSplitView', function() {

  function setOrientation (scope, element, newOrient, currentOrient) {

    element.removeClass ('horizontal');
    element.removeClass ('vertical');

    switch (newOrient) {
      case undefined:
      case null:
      case "":
        scope.orientation = "horizontal";
        return;
      case "horizontal":
      case "vertical":
        break;
      default:
        console.warn ("Unsuported SplitView.orientation: " + newOrient);
        return;
    }

    element.addClass (newOrient);
  }

  function setMode (scope, element, newMode, currentMode) {

    element.removeClass ('tablet');
    element.removeClass ('phone');

    switch (newMode) {
      case undefined:
      case null:
      case "":
        scope.mode = "tablet";
        return;
      case "tablet":
      case "phone":
        break;
      default:
        console.warn ("Unsuported SplitView.mode: " + newMode);
        return;
    }

    element.addClass (newMode);
  }

  return {
    restrict: 'E',

    transclude: true,

    replace: true,

    template: "

",

    scope: {
      mode: "@",
      orientation: "@"
    },

    controller: function ($scope) {
      $scope.mode = "tablet";
      $scope.orientation = "vertical";
    },

    link: function (scope, element, attrs, controller, transclude) {

      setMode (scope, element, scope.mode);
      setOrientation (scope, element, scope.orientation);

      scope.$watch ('orientation', function (newOrientation, currentOrientation) {
        if (angular.isUndefined (newOrientation)) {
          return;
        }
        setOrientation (scope, element, newOrientation, currentOrientation);
      });

      scope.$watch ('mode', function (newMode, currentMode) {
        if (angular.isUndefined (newMode)) {
          return;
        }
        setMode (scope, element, newMode, currentMode);
      });

      element.on ('$destroy', function() {
        console.log ("vsButton $destroy");
      });
    }
  };
});
<|endoftext|>